#include <linux/module.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/msi.h>
#include <linux/mutex.h>
#define EN_CDEV     // 使能 字符设备
#ifdef EN_CDEV
#include <linux/cdev.h>
#endif // EN_CDEV
#define EN_IRQ      // 使能 IRQ
#ifdef EN_IRQ
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#endif  // EN_IRQ
#define EN_CANFD    // 使能 CANFD IP
#if (defined(EN_CAN) || defined(EN_CANFD))
#include <linux/spinlock.h>
#include <linux/semaphore.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/circ_buf.h>
#include <linux/bitfield.h>
#include "pcie_canfd.h"
#include "xcan_dev.h"
#endif  // (defined(EN_CAN) || defined(EN_CANFD))

#define DRV_NAME            "pcie_canfd"
#define DEV_NUM             1
#ifndef PCI_STD_NUM_BARS
#define PCI_STD_NUM_BARS    6       /* Number of standard BARs */
#endif
#define PCI_BAR0            0
#define PCI_BAR1            1

#ifdef EN_IRQ
/*
 * 系统支持的最大中断资源数量：
 *  1. MSI-X: PCI 3.0+ 规范支持的最大向量数 (2048)
 *  2. MSI:   PCI 规范支持的最大向量数 (32)
 *  3. Legacy: 传统PCI设备支持的最大中断数 (1)
 * 注意：实际可用数量受设备能力和系统资源限制
 */
#define IRQ_MAX_VEC_MSIX        2048
#define IRQ_MAX_VEC_MSI         32
#define IRQ_MAX_VEC_LGCY        1
#define IRQ_NAME                "irq_can"
#define IRQ_VECTOR_START        1
#define IRQ_VECTOR_NUM          DEV_NUM

// 中断寄存器定义
#define IRQ_MSI_MASK_REG        0x5C
// 中断向量定义
#define IR1_VEC_MSI_CANFD_0     1
#define IR1_VEC_MSI_CANFD_1     2
#define IR1_VEC_MSI_CANFD_2     3
#define IR1_VEC_MSI_CANFD_3     4
#define IR1_VEC_MSI_CANFD_4     5
#define IR1_VEC_MSI_CANFD_5     6
#define IR1_VEC_MSI_CANFD_6     7
#define IR1_VEC_MSI_CANFD_7     8
#define IR1_VEC_MSI_CANFD_8     9
#define IR1_VEC_MSI_CANFD_9     10
#endif // EN_IRQ

#if (defined(EN_CAN) || defined(EN_CANFD))
// CANFD 读写寄存器定义
#define CAN_FD_WR_ADDR_REG      0x0C
#define CAN_FD_WR_DATA_REG      0x10
#define CAN_FD_RD_ADDR_REG      0x14
#define CAN_FD_RD_DATA_REG      0x18
// CANFD 寄存器位偏移定义
#define CAN_FD_DEV_ID_SHIFT     16

/* CAN registers set */
enum xcan_reg {
    XCAN_SRR_OFFSET     = 0x00,     /* Software reset */
    XCAN_MSR_OFFSET     = 0x04,     /* Mode select */
    XCAN_BRPR_OFFSET    = 0x08,     /* Baud rate prescaler */
    XCAN_BTR_OFFSET     = 0x0C,     /* Bit timing */
    XCAN_ECR_OFFSET     = 0x10,     /* Error counter */
    XCAN_ESR_OFFSET     = 0x14,     /* Error status */
    XCAN_SR_OFFSET      = 0x18,     /* Status */
    XCAN_ISR_OFFSET     = 0x1C,     /* Interrupt status */
    XCAN_IER_OFFSET     = 0x20,     /* Interrupt enable */
    XCAN_ICR_OFFSET     = 0x24,     /* Interrupt clear */

    /* not on CAN FD cores */
    XCAN_TXFIFO_OFFSET  = 0x30,     /* TX FIFO base */
    XCAN_RXFIFO_OFFSET  = 0x50,     /* RX FIFO base */
    XCAN_AFR_OFFSET     = 0x60,     /* Acceptance Filter */

    /* only on CAN FD cores */
    XCAN_F_BRPR_OFFSET          = 0x088,        /* Data Phase Baud Rate Prescalar */
    XCAN_F_BTR_OFFSET           = 0x08C,        /* Data Phase Bit Timing */
    XCAN_TRR_OFFSET             = 0x0090,       /* TX Buffer Ready Request */
    XCAN_AFR_EXT_OFFSET         = 0x00E0,       /* Acceptance Filter */
    XCAN_FSR_OFFSET             = 0x00E8,       /* RX FIFO Status */
    XCAN_TXMSG_BASE_OFFSET      = 0x0100,       /* TX Message Space */
    XCAN_RXMSG_BASE_OFFSET      = 0x1100,       /* RX Message Space */
    XCAN_RXMSG_2_BASE_OFFSET    = 0x2100,       /* RX Message Space */
    XCAN_AFR_2_MASK_OFFSET      = 0x0A00,       /* Acceptance Filter MASK */
    XCAN_AFR_2_ID_OFFSET        = 0x0A04,       /* Acceptance Filter ID */
};

#define XCAN_FRAME_ID_OFFSET(frame_base)    ((frame_base) + 0x00)
#define XCAN_FRAME_DLC_OFFSET(frame_base)   ((frame_base) + 0x04)
#define XCAN_FRAME_DW1_OFFSET(frame_base)   ((frame_base) + 0x08)
#define XCAN_FRAME_DW2_OFFSET(frame_base)   ((frame_base) + 0x0C)
#define XCANFD_FRAME_DW_OFFSET(frame_base)  ((frame_base) + 0x08)

#define XCAN_CANFD_FRAME_SIZE           0x48
#define XCAN_TXMSG_FRAME_OFFSET(n)      (XCAN_TXMSG_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))
#define XCAN_RXMSG_FRAME_OFFSET(n)      (XCAN_RXMSG_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))
#define XCAN_RXMSG_2_FRAME_OFFSET(n)    (XCAN_RXMSG_2_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))

/* the single TX mailbox used by this driver on CAN FD HW */
#define XCAN_TX_MAILBOX_IDX     0

/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
#define XCAN_SRR_CEN_MASK       0x00000002      /* CAN enable */
#define XCAN_SRR_RESET_MASK     0x00000001      /* Soft Reset the CAN core */
#define XCAN_MSR_LBACK_MASK     0x00000002      /* Loop back mode select */
#define XCAN_MSR_SLEEP_MASK     0x00000001      /* Sleep mode select */
#define XCAN_BRPR_BRP_MASK      0x000000FF      /* Baud rate prescaler */
#define XCAN_BTR_SJW_MASK       0x00000180      /* Synchronous jump width */
#define XCAN_BTR_TS2_MASK       0x00000070      /* Time segment 2 */
#define XCAN_BTR_TS1_MASK       0x0000000F      /* Time segment 1 */
#define XCAN_BTR_SJW_MASK_CANFD 0x000F0000      /* Synchronous jump width */
#define XCAN_BTR_TS2_MASK_CANFD 0x00000F00      /* Time segment 2 */
#define XCAN_BTR_TS1_MASK_CANFD 0x0000003F      /* Time segment 1 */
#define XCAN_ECR_REC_MASK       0x0000FF00      /* Receive error counter */
#define XCAN_ECR_TEC_MASK       0x000000FF      /* Transmit error counter */
#define XCAN_ESR_ACKER_MASK     0x00000010      /* ACK error */
#define XCAN_ESR_BERR_MASK      0x00000008      /* Bit error */
#define XCAN_ESR_STER_MASK      0x00000004      /* Stuff error */
#define XCAN_ESR_FMER_MASK      0x00000002      /* Form error */
#define XCAN_ESR_CRCER_MASK     0x00000001      /* CRC error */
#define XCAN_SR_TXFLL_MASK      0x00000400      /* TX FIFO is full */
#define XCAN_SR_ESTAT_MASK      0x00000180      /* Error status */
#define XCAN_SR_ERRWRN_MASK     0x00000040      /* Error warning */
#define XCAN_SR_NORMAL_MASK     0x00000008      /* Normal mode */
#define XCAN_SR_LBACK_MASK      0x00000002      /* Loop back mode */
#define XCAN_SR_CONFIG_MASK     0x00000001      /* Configuration mode */
#define XCAN_IXR_RXMNF_MASK     0x00020000      /* RX match not finished */
#define XCAN_IXR_TXFEMP_MASK    0x00004000      /* TX FIFO Empty */
#define XCAN_IXR_WKUP_MASK      0x00000800      /* Wake up interrupt */
#define XCAN_IXR_SLP_MASK       0x00000400      /* Sleep interrupt */
#define XCAN_IXR_BSOFF_MASK     0x00000200      /* Bus off interrupt */
#define XCAN_IXR_ERROR_MASK     0x00000100      /* Error interrupt */
#define XCAN_IXR_RXNEMP_MASK    0x00000080      /* RX FIFO NotEmpty intr */
#define XCAN_IXR_RXOFLW_MASK    0x00000040      /* RX FIFO Overflow intr */
#define XCAN_IXR_RXOK_MASK      0x00000010      /* Message received intr */
#define XCAN_IXR_TXFLL_MASK     0x00000004      /* Tx FIFO Full intr */
#define XCAN_IXR_TXOK_MASK      0x00000002      /* TX successful intr */
#define XCAN_IXR_ARBLST_MASK    0x00000001      /* Arbitration lost intr */
#define XCAN_IDR_ID1_MASK       0xFFE00000      /* Standard msg identifier */
#define XCAN_IDR_SRR_MASK       0x00100000      /* Substitute remote TXreq */
#define XCAN_IDR_IDE_MASK       0x00080000      /* Identifier extension */
#define XCAN_IDR_ID2_MASK       0x0007FFFE      /* Extended message ident */
#define XCAN_IDR_RTR_MASK       0x00000001      /* Remote TX request */
#define XCAN_DLCR_DLC_MASK      0xF0000000      /* Data length code */
#define XCAN_FSR_FL_MASK        0x00003F00      /* RX Fill Level */
#define XCAN_2_FSR_FL_MASK      0x00007F00      /* RX Fill Level */
#define XCAN_FSR_IRI_MASK       0x00000080      /* RX Increment Read Index */
#define XCAN_FSR_RI_MASK        0x0000001F      /* RX Read Index */
#define XCAN_2_FSR_RI_MASK      0x0000003F      /* RX Read Index */
#define XCAN_DLCR_EDL_MASK      0x08000000      /* EDL Mask in DLC */
#define XCAN_DLCR_BRS_MASK      0x04000000      /* BRS Mask in DLC */

/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
#define XCAN_BTR_SJW_SHIFT          7           /* Synchronous jump width */
#define XCAN_BTR_TS2_SHIFT          4           /* Time segment 2 */
#define XCAN_BTR_SJW_SHIFT_CANFD    16          /* Synchronous jump width */
#define XCAN_BTR_TS2_SHIFT_CANFD    8           /* Time segment 2 */
#define XCAN_IDR_ID1_SHIFT          21          /* Standard Messg Identifier */
#define XCAN_IDR_ID2_SHIFT          1           /* Extended Message Identifier */
#define XCAN_DLCR_DLC_SHIFT         28          /* Data length code */
#define XCAN_ESR_REC_SHIFT          8           /* Rx Error Count */

/* CAN frame length constants */
#define XCAN_FRAME_MAX_DATA_LEN 8
#define XCANFD_DW_BYTES         4
#define XCAN_TIMEOUT            (1 * HZ)

/* TX-FIFO-empty interrupt available */
#define XCAN_FLAG_TXFEMP        0x0001
/* RX Match Not Finished interrupt available */
#define XCAN_FLAG_RXMNF         0x0002
/* Extended acceptance filters with control at 0xE0 */
#define XCAN_FLAG_EXT_FILTERS   0x0004
/* TX mailboxes instead of TX FIFO */
#define XCAN_FLAG_TX_MAILBOXES  0x0008
/* RX FIFO with each buffer in separate registers at 0x1100
 * instead of the regular FIFO at 0x50
 */
#define XCAN_FLAG_RX_FIFO_MULTI 0x0010
#define XCAN_FLAG_CANFD_2       0x0020
#endif // (defined(EN_CAN) || defined(EN_CANFD))

#ifdef EN_CDEV
struct char_dev_t {
    struct device *dev;     // 设备描述符
    u8 index;               // 设备索引号
    char name[16];          // 设备名
    dev_t devno;            // 设备号
    struct cdev cdev;       // 字符设备
};
#endif // EN_CDEV

#ifdef EN_IRQ
// 中断数据结构
struct irq_t {
    struct device *dev;                                     // 设备描述符
    void __iomem *reg_base;                                 // 寄存器空间映射（内核虚拟地址）
    int mode;                                               // 中断模式
    unsigned long flags;                                    // 中断标识
    int num;                                                // 中断数量
    int vector[IRQ_MAX_VEC_MSIX];                           // 中断向量
    int index;                                              // 中断索引号
    atomic_t count;                                         // 中断计数
    struct msix_entry msix_entries[IRQ_MAX_VEC_MSIX];       // MSI-X 表项
};
#endif  // EN_IRQ
#if (defined(EN_CAN) || defined(EN_CANFD))
#ifdef EN_CANFD
struct canfd_reg_t {
    u32 brpr;   // 波特率预分频寄存器
    u32 btr;    // 位定时寄存器
};
#endif // EN_CANFD
struct can_reg_t {
    u32 isr;    // 中断状态寄存器
    u32 ier;    // 中断使能寄存器
    u32 sr;     // 状态寄存器
    u32 ecr;    // 错误计数寄存器
    u32 esr;    // 错误状态寄存器
    u32 brpr;   // 波特率预分频寄存器
    u32 btr;    // 位定时寄存器
#ifdef EN_CANFD
    struct canfd_reg_t fd;     // CANFD 专有寄存器
#endif // EN_CANFD
};
#define CIRC_BUF_SIZE   256     /* 缓冲区总大小，必须是 2 的幂次方 */
/* 环形缓冲区 */
struct circ_buf_t {
    size_t size;        /* 缓冲区总大小，必须是 2 的幂次方 */
    size_t head;        /* 写索引 */
    size_t tail;        /* 读索引 */
    struct canfd_msg_t msg[CIRC_BUF_SIZE];
};
struct xcan_filter_t {
    u32 id;
    u32 mask;
};
enum xcan_ip_type {
	XAXI_CAN = 0,
	XZYNQ_CANPS,
	XAXI_CANFD,
	XAXI_CANFD_2_0,
};
struct xcan_devtype_data {
	enum xcan_ip_type cantype;
	unsigned int flags;
	const struct can_bittiming_const *bittiming_const;
	const char *bus_clk_name;
	unsigned int btr_ts2_shift;
	unsigned int btr_sjw_shift;
};
/**
 * struct xcan_priv - This definition define CAN driver instance
 * @can:			CAN private data structure.
 * @tx_lock:			Lock for synchronizing TX interrupt handling
 * @tx_head:			Tx CAN packets ready to send on the queue
 * @tx_tail:			Tx CAN packets successfully sended on the queue
 * @tx_max:			Maximum number packets the driver can send
 * @napi:			NAPI structure
 * @read_reg:			For reading data from CAN registers
 * @write_reg:			For writing data to CAN registers
 * @dev:			Network device data structure
 * @reg_base:			Ioremapped address to registers
 * @irq_flags:			For request_irq()
 * @bus_clk:			Pointer to struct clk
 * @can_clk:			Pointer to struct clk
 * @devtype:			Device type specific constants
 */
struct xcan_priv {      // CANFD数据结构
    struct mutex lock;                  /* 互斥锁 */
    u8 index;                           /* 索引号 */
    struct work_struct work;
    struct xcan_device_stats stats;     /* 状态 */
    int restart_ms;                     /* 延时重启设备 */
    struct delayed_work restart_work;   /* 重启设备延时队列 */
    struct circ_buf_t rx_circ;          /* 接收环形缓冲区 */
    spinlock_t rx_splock;               /* 自旋锁保护缓冲区（中断安全） */
    wait_queue_head_t rx_wqh;           /* 接收等待队列 */
    struct circ_buf_t tx_circ;          /* 发送环形缓冲区 */
    spinlock_t tx_splock;               /* 自旋锁保护缓冲区（中断安全） */
    struct xcan_filter_t filter;        /* 帧过滤 */
#ifdef EN_CANFD
    struct canfd_frame rx_frame;        // 接收帧
    struct canfd_frame tx_frame;        // 发送帧
#endif // EN_CANFD
    struct can_priv can;                // CAN 设备描述符
    spinlock_t tx_lock;                 /* Lock for synchronizing TX interrupt handling */
    unsigned int tx_head;
    unsigned int tx_tail;
    unsigned int tx_max;
    u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
    void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg, u32 val);
    struct device *dev;                 // 设备描述符
    void __iomem *reg_base;             // 寄存器空间映射（内核虚拟地址）
    struct xcan_devtype_data devtype;
};


/* AXI CANFD 2.0 Arbitration Bittiming constants as per AXI CANFD 2.0 spec */
static const struct can_bittiming_const xcan_bittiming_const_canfd2 = {
	.name = DRV_NAME,
	.tseg1_min = 1,
	.tseg1_max = 256,
	.tseg2_min = 1,
	.tseg2_max = 128,
	.sjw_max = 128,
	.brp_min = 2,
	.brp_max = 256,
	.brp_inc = 1,
};
/* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */
static struct can_bittiming_const xcan_data_bittiming_const_canfd2 = {
	.name = DRV_NAME,
	.tseg1_min = 1,
	.tseg1_max = 32,
	.tseg2_min = 1,
	.tseg2_max = 16,
	.sjw_max = 16,
	.brp_min = 2,
	.brp_max = 256,
	.brp_inc = 1,
};
static const struct xcan_devtype_data xcan_canfd2_data = {
	.cantype = XAXI_CANFD_2_0,
	.flags = XCAN_FLAG_EXT_FILTERS |
		 XCAN_FLAG_RXMNF |
		 XCAN_FLAG_TX_MAILBOXES |
		 XCAN_FLAG_CANFD_2 |
		 XCAN_FLAG_RX_FIFO_MULTI,
	.bittiming_const = &xcan_bittiming_const_canfd2,
	.btr_ts2_shift = XCAN_BTR_TS2_SHIFT_CANFD,
	.btr_sjw_shift = XCAN_BTR_SJW_SHIFT_CANFD,
	.bus_clk_name = "s_axi_aclk",
};
#endif  // (defined(EN_CAN) || defined(EN_CANFD))

// 设备特定数据结构
struct pcie_cdev_t {
    struct device *dev;                         // 设备描述符
    char name[64];                              // 唯一设备名称
    void __iomem *bar[PCI_STD_NUM_BARS];            // 映射的寄存器基地址
    resource_size_t bar_len[PCI_STD_NUM_BARS];      // 寄存器区域长度
    struct mutex lock;                          // 同步机制(互斥锁)
#ifdef EN_CDEV
    struct class *char_class;   /* 共享类：统一管理所有设备的/sys/class接口 */
    struct char_dev_t char_dev[DEV_NUM];        // 字符设备
#endif // EN_CDEV
#ifdef EN_IRQ
    struct irq_t irq;                           // 中断
#endif // EN_IRQ
#if (defined(EN_CAN) || defined(EN_CANFD))
    struct xcan_priv xcan[DEV_NUM];             // CAN
#endif  // (defined(EN_CAN) || defined(EN_CANFD))

};

// 文件操作函数声明
static int pcie_cdev_open(struct inode *inode, struct file *filp);
static int pcie_cdev_release(struct inode *inode, struct file *filp);
static ssize_t pcie_cdev_read(struct file *filp, char __user *buf, 
                              size_t count, loff_t *ppos);
static ssize_t pcie_cdev_write(struct file *filp, const char __user *buf, 
                               size_t count, loff_t *ppos);
static long pcie_cdev_ioctl(struct file *filp, unsigned int cmd, 
                            unsigned long arg);
static irqreturn_t xcan_interrupt(int irq, void *dev_id);

// 文件操作结构体
static const struct file_operations pcie_cdev_fops = {
    .owner = THIS_MODULE,
    .open = pcie_cdev_open,
    .release = pcie_cdev_release,
    .read = pcie_cdev_read,
    .write = pcie_cdev_write,
    .unlocked_ioctl = pcie_cdev_ioctl,
    .poll = NULL,
    .llseek = no_llseek, // 不支持 seek
};

#if (defined(EN_CAN) || defined(EN_CANFD))
static int xcan_frame_to_msg(struct canfd_frame cf, struct canfd_msg_t *msg)
{
    int ret = 0;

    if (!msg) {
        return -1;
    }
    memset(msg, 0, sizeof(struct canfd_msg_t));
    /*
     * 32 bit CAN_ID + EFF/RTR/ERR flags
     *
     * bit 0-28  : CAN identifier (11/29 bit)
     * bit 29    : error message frame flag (0 = data frame, 1 = error message)
     * bit 30    : remote transmission request flag (1 = rtr frame)
     * bit 31    : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
     */
    if (cf.can_id & CAN_EFF_FLAG) {
        msg->fmt = 1;
    } else {
        msg->fmt = 0;
    }
    if (cf.can_id & CAN_RTR_FLAG) {
        msg->rtr = 1;
    } else {
        msg->rtr = 0;
    }
    msg->id = (((cf.can_id & ~CAN_EFF_FLAG) & ~CAN_RTR_FLAG) & ~CAN_ERR_FLAG);
    /* frame payload length in byte */
    msg->dlc = cf.len;
    /* additional flags for CAN FD */
    msg->flg = cf.flags;
    memcpy(msg->data, cf.data, cf.len);

    return ret;
}
static int xcan_msg_to_frame(struct canfd_msg_t msg, struct canfd_frame *cf)
{
    int ret = 0;

    if (!cf) {
        return -1;
    }
    memset(cf, 0, sizeof(struct canfd_frame));
    /*
     * 32 bit CAN_ID + EFF/RTR/ERR flags
     *
     * bit 0-28  : CAN identifier (11/29 bit)
     * bit 29    : error message frame flag (0 = data frame, 1 = error message)
     * bit 30    : remote transmission request flag (1 = rtr frame)
     * bit 31    : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
     */
    if (0 == msg.fmt) {
        cf->can_id = msg.id;
        if (1 == msg.rtr)
            cf->can_id |= CAN_RTR_FLAG;
    } else {
        cf->can_id = msg.id;
        cf->can_id |= CAN_EFF_FLAG;
        if (1 == msg.rtr)
            cf->can_id |= CAN_RTR_FLAG;
    }
    /* frame payload length in byte */
    cf->len = msg.dlc;
    /* additional flags for CAN FD */
    cf->flags = msg.flg;
    memcpy(cf->data, msg.data, msg.dlc);

    return ret;
}
/* 检查缓冲区是否为空 */
static int circ_buf_empty(struct circ_buf_t *rx_circ) {
    return (rx_circ->head == rx_circ->tail);
}
/* 检查缓冲区是否已满 */
static int circ_buf_full(struct circ_buf_t *rx_circ) {
    return (((rx_circ->head + 1) % rx_circ->size) == rx_circ->tail);
}

/**
 * xcan_write_reg_le - Write a value to the device register little endian
 * @priv:	Driver private data structure
 * @reg:	Register offset
 * @val:	Value to write at the Register offset
 *
 * Write data to the paricular CAN register
 */
static void xcan_write_reg_le(const struct xcan_priv *priv, enum xcan_reg reg, u32 val)
{
    /* FPGA: can fd device id, start from 1 */
    u32 wreg = ((priv->index + 1) << CAN_FD_DEV_ID_SHIFT | reg);
    iowrite32(wreg, priv->reg_base + CAN_FD_WR_ADDR_REG);       // 写寄存器地址
    iowrite32(val, priv->reg_base + CAN_FD_WR_DATA_REG);        // 写寄存器数据
}
/**
 * xcan_read_reg_le - Read a value from the device register little endian
 * @priv:	Driver private data structure
 * @reg:	Register offset
 *
 * Read data from the particular CAN register
 * Return: value read from the CAN register
 */
static u32 xcan_read_reg_le(const struct xcan_priv *priv, enum xcan_reg reg)
{
    /* FPGA: can fd device id, start from 1 */
    u32 rreg = ((priv->index + 1) << CAN_FD_DEV_ID_SHIFT | reg);
    iowrite32(rreg, priv->reg_base + CAN_FD_RD_ADDR_REG);       // 读寄存器地址
    return ioread32(priv->reg_base + CAN_FD_RD_DATA_REG);       // 读寄存器数据
}
/**
 * xcan_rx_int_mask - Get the mask for the receive interrupt
 * @priv:	Driver private data structure
 *
 * Return: The receive interrupt mask used by the driver on this HW
 */
static u32 xcan_rx_int_mask(const struct xcan_priv *priv)
{
	/* RXNEMP is better suited for our use case as it cannot be cleared
	 * while the FIFO is non-empty, but CAN FD HW does not have it
	 */
	if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI)
		return XCAN_IXR_RXOK_MASK;
	else
		return XCAN_IXR_RXNEMP_MASK;
}
/**
 * set_reset_mode - Resets the CAN device mode
 * @ndev:	Pointer to net_device structure
 *
 * This is the driver reset mode routine.The driver
 * enters into configuration mode.
 *
 * Return: 0 on success and failure value on error
 */
static int set_reset_mode(struct xcan_priv *priv)
{
	unsigned long timeout;

	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);

    dev_info(priv->dev, "SRR=0x%08x, SR=0x%08x",
             priv->read_reg(priv, XCAN_SRR_OFFSET),
             priv->read_reg(priv, XCAN_SR_OFFSET));

	timeout = jiffies + XCAN_TIMEOUT;
	while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_CONFIG_MASK)) {
		if (time_after(jiffies, timeout)) {
			dev_warn(priv->dev, "timed out for config mode");

            dev_info(priv->dev, "SRR=0x%08x, SR=0x%08x",
                    priv->read_reg(priv, XCAN_SRR_OFFSET),
                    priv->read_reg(priv, XCAN_SR_OFFSET));

			return -ETIMEDOUT;
		}
		usleep_range(500, 10000);
	}

	/* reset clears FIFOs */
	priv->tx_head = 0;
	priv->tx_tail = 0;

	return 0;
}

/**
 * xcan_set_bittiming - CAN set bit timing routine
 * @ndev:	Pointer to net_device structure
 *
 * This is the driver set bittiming  routine.
 * Return: 0 on success and failure value on error
 */
static int xcan_set_bittiming(struct xcan_priv *priv)
{
	struct can_bittiming *bt = &priv->can.bittiming;
	struct can_bittiming *dbt = &priv->can.data_bittiming;
	u32 btr0, btr1;
	u32 is_config_mode;

	/* Check whether Xilinx CAN is in configuration mode.
	 * It cannot set bit timing if Xilinx CAN is not in configuration mode.
	 */
	is_config_mode = priv->read_reg(priv, XCAN_SR_OFFSET) &
				XCAN_SR_CONFIG_MASK;
	if (!is_config_mode) {
		dev_warn(priv->dev,
			     "BUG! Cannot set bittiming - CAN is not in config mode");
		return -EPERM;
	}

	/* Setting Baud Rate prescalar value in BRPR Register */
	btr0 = (bt->brp - 1);

	/* Setting Time Segment 1 in BTR Register */
	btr1 = (bt->prop_seg + bt->phase_seg1 - 1);

	/* Setting Time Segment 2 in BTR Register */
	btr1 |= (bt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift;

	/* Setting Synchronous jump width in BTR Register */
	btr1 |= (bt->sjw - 1) << priv->devtype.btr_sjw_shift;

	priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0);
	priv->write_reg(priv, XCAN_BTR_OFFSET, btr1);

	if (priv->devtype.cantype == XAXI_CANFD ||
	    priv->devtype.cantype == XAXI_CANFD_2_0) {
		/* Setting Baud Rate prescalar value in F_BRPR Register */
		btr0 = dbt->brp - 1;

		/* Setting Time Segment 1 in BTR Register */
		btr1 = dbt->prop_seg + dbt->phase_seg1 - 1;

		/* Setting Time Segment 2 in BTR Register */
		btr1 |= (dbt->phase_seg2 - 1) << priv->devtype.btr_ts2_shift;

		/* Setting Synchronous jump width in BTR Register */
		btr1 |= (dbt->sjw - 1) << priv->devtype.btr_sjw_shift;

		priv->write_reg(priv, XCAN_F_BRPR_OFFSET, btr0);
		priv->write_reg(priv, XCAN_F_BTR_OFFSET, btr1);
	}

	dev_info(priv->dev, "BRPR=0x%08x, BTR=0x%08x",
		   priv->read_reg(priv, XCAN_BRPR_OFFSET),
		   priv->read_reg(priv, XCAN_BTR_OFFSET));

	return 0;
}

/**
 * xcan_chip_start - This the drivers start routine
 * @ndev:	Pointer to net_device structure
 *
 * This is the drivers start routine.
 * Based on the State of the CAN device it puts
 * the CAN device into a proper mode.
 *
 * Return: 0 on success and failure value on error
 */
static int xcan_chip_start(struct xcan_priv *priv)
{
	u32 reg_msr;
	int err;
	u32 ier;

	/* Check if it is in reset mode */
	err = set_reset_mode(priv);
	if (err < 0)
		return err;

	err = xcan_set_bittiming(priv);
	if (err < 0)
		return err;

	/* Enable interrupts
	 *
	 * We enable the ERROR interrupt even with
	 * CAN_CTRLMODE_BERR_REPORTING disabled as there is no
	 * dedicated interrupt for a state change to
	 * ERROR_WARNING/ERROR_PASSIVE.
	 */
	ier = XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |
		XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK |
		XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
		XCAN_IXR_ARBLST_MASK | xcan_rx_int_mask(priv);

	if (priv->devtype.flags & XCAN_FLAG_RXMNF)
		ier |= XCAN_IXR_RXMNF_MASK;

	priv->write_reg(priv, XCAN_IER_OFFSET, ier);

	/* Check whether it is loopback mode or normal mode  */
	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
		reg_msr = XCAN_MSR_LBACK_MASK;
	else
		reg_msr = 0x0;

	/* enable the first extended filter, if any, as cores with extended
	 * filtering default to non-receipt if all filters are disabled
	 */
	if (priv->devtype.flags & XCAN_FLAG_EXT_FILTERS)
		priv->write_reg(priv, XCAN_AFR_EXT_OFFSET, 0x00000001);

	priv->write_reg(priv, XCAN_MSR_OFFSET, reg_msr);
	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);

	dev_info(priv->dev, "status:#x%08x",
		   priv->read_reg(priv, XCAN_SR_OFFSET));

	priv->can.state = CAN_STATE_ERROR_ACTIVE;
	return 0;
}
/**
 * xcan_do_set_mode - This sets the mode of the driver
 * @ndev:	Pointer to net_device structure
 * @mode:	Tells the mode of the driver
 *
 * This check the drivers state and calls the
 * the corresponding modes to set.
 *
 * Return: 0 on success and failure value on error
 */
static int xcan_do_set_mode(struct xcan_priv *priv, enum can_mode mode)
{
	int ret;

	switch (mode) {
	case CAN_MODE_START:
		ret = xcan_chip_start(priv);
		if (ret < 0) {
			dev_err(priv->dev, "xcan_chip_start failed!");
			return ret;
		}
		// netif_wake_queue(ndev);
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}
/**
 * xcan_write_frame - Write a frame to HW
 * @ndev:		Pointer to net_device structure
 * @skb:		sk_buff pointer that contains data to be Txed
 * @frame_offset:	Register offset to write the frame to
 */
static void xcan_write_frame(struct xcan_priv *priv, struct canfd_frame *buf, 
			     int frame_offset)
{
	u32 id, dlc, data[2] = {0, 0};
	struct canfd_frame *cf = buf;
	u32 ramoff, dwindex = 0, i;

	/* Watch carefully on the bit sequence */
	if (cf->can_id & CAN_EFF_FLAG) {
		/* Extended CAN ID format */
		id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT) &
			XCAN_IDR_ID2_MASK;
		id |= (((cf->can_id & CAN_EFF_MASK) >>
			(CAN_EFF_ID_BITS - CAN_SFF_ID_BITS)) <<
			XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK;

		/* The substibute remote TX request bit should be "1"
		 * for extended frames as in the Xilinx CAN datasheet
		 */
		id |= XCAN_IDR_IDE_MASK | XCAN_IDR_SRR_MASK;

		if (cf->can_id & CAN_RTR_FLAG)
			/* Extended frames remote TX request */
			id |= XCAN_IDR_RTR_MASK;
	} else {
		/* Standard CAN ID format */
		id = ((cf->can_id & CAN_SFF_MASK) << XCAN_IDR_ID1_SHIFT) &
			XCAN_IDR_ID1_MASK;

		if (cf->can_id & CAN_RTR_FLAG)
			/* Standard frames remote TX request */
			id |= XCAN_IDR_SRR_MASK;
	}

	dlc = can_len2dlc(cf->len) << XCAN_DLCR_DLC_SHIFT;
	// if (can_is_canfd_skb(skb)) {
	if (1 == cf->flags) {
		if (cf->flags & CANFD_BRS)
			dlc |= XCAN_DLCR_BRS_MASK;
		dlc |= XCAN_DLCR_EDL_MASK;
	}

	// if (!(priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) &&
	//     (priv->devtype.flags & XCAN_FLAG_TXFEMP))
	// 	can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
	// else
	// 	can_put_echo_skb(skb, ndev, 0);

	priv->tx_head++;

	priv->write_reg(priv, XCAN_FRAME_ID_OFFSET(frame_offset), id);
	/* If the CAN frame is RTR frame this write triggers transmission
	 * (not on CAN FD)
	 */
	priv->write_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_offset), dlc);
	if (priv->devtype.cantype == XAXI_CANFD ||
	    priv->devtype.cantype == XAXI_CANFD_2_0) {
		for (i = 0; i < cf->len; i += 4) {
			ramoff = XCANFD_FRAME_DW_OFFSET(frame_offset) +
					(dwindex * XCANFD_DW_BYTES);
			priv->write_reg(priv, ramoff,
					be32_to_cpup((__be32 *)(cf->data + i)));
			dwindex++;
		}
	} else {
		if (cf->len > 0)
			data[0] = be32_to_cpup((__be32 *)(cf->data + 0));
		if (cf->len > 4)
			data[1] = be32_to_cpup((__be32 *)(cf->data + 4));

		if (!(cf->can_id & CAN_RTR_FLAG)) {
			priv->write_reg(priv,
					XCAN_FRAME_DW1_OFFSET(frame_offset),
					data[0]);
			/* If the CAN frame is Standard/Extended frame this
			 * write triggers transmission (not on CAN FD)
			 */
			priv->write_reg(priv,
					XCAN_FRAME_DW2_OFFSET(frame_offset),
					data[1]);
		}
	}
}

/**
 * xcan_start_xmit_fifo - Starts the transmission (FIFO mode)
 * @skb:	sk_buff pointer that contains data to be Txed
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 on success, -ENOSPC if FIFO is full.
 */
static int xcan_start_xmit_fifo(struct canfd_frame *buf, struct xcan_priv *priv)
{
	unsigned long flags;

	/* Check if the TX buffer is full */
	if (unlikely(priv->read_reg(priv, XCAN_SR_OFFSET) &
			XCAN_SR_TXFLL_MASK))
		return -ENOSPC;

	spin_lock_irqsave(&priv->tx_lock, flags);

	xcan_write_frame(priv, buf, XCAN_TXFIFO_OFFSET);

	/* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */
	if (priv->tx_max > 1)
		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK);

	/* Check if the TX buffer is full */
	if ((priv->tx_head - priv->tx_tail) == priv->tx_max)
		// netif_stop_queue(ndev);

	spin_unlock_irqrestore(&priv->tx_lock, flags);

	return 0;
}

/**
 * xcan_start_xmit_mailbox - Starts the transmission (mailbox mode)
 * @skb:	sk_buff pointer that contains data to be Txed
 * @ndev:	Pointer to net_device structure
 *
 * Return: 0 on success, -ENOSPC if there is no space
 */
static int xcan_start_xmit_mailbox(struct canfd_frame *buf, struct xcan_priv *priv)
{
	unsigned long flags;

	if (unlikely(priv->read_reg(priv, XCAN_TRR_OFFSET) &
		     BIT(XCAN_TX_MAILBOX_IDX)))
		return -ENOSPC;

	spin_lock_irqsave(&priv->tx_lock, flags);

	xcan_write_frame(priv, buf, 
			 XCAN_TXMSG_FRAME_OFFSET(XCAN_TX_MAILBOX_IDX));

	/* Mark buffer as ready for transmit */
	priv->write_reg(priv, XCAN_TRR_OFFSET, BIT(XCAN_TX_MAILBOX_IDX));

	// netif_stop_queue(ndev);

	spin_unlock_irqrestore(&priv->tx_lock, flags);

	return 0;
}

/**
 * xcan_start_xmit - Starts the transmission
 * @skb:	sk_buff pointer that contains data to be Txed
 * @ndev:	Pointer to net_device structure
 *
 * This function is invoked from upper layers to initiate transmission.
 *
 * Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY when the tx queue is full
 */
static int xcan_start_xmit(struct canfd_frame *buf, struct xcan_priv *priv)
{
	int ret;

	if (priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES)
		ret = xcan_start_xmit_mailbox(buf, priv);
	else
		ret = xcan_start_xmit_fifo(buf, priv);

	if (ret < 0) {
		dev_err(priv->dev, "BUG!, TX full when queue awake!");
		// netif_stop_queue(ndev);
		return -1;
	}

	return 0;
}
/**
 * xcan_rx -  Is called from CAN isr to complete the received
 *		frame  processing
 * @ndev:	Pointer to net_device structure
 * @frame_base:	Register offset to the frame to be read
 *
 * This function is invoked from the CAN isr(poll) to process the Rx frames. It
 * does minimal processing and invokes "netif_receive_skb" to complete further
 * processing.
 * Return: 1 on success and 0 on failure.
 */
static int xcan_rx(struct xcan_priv *priv, int frame_base)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	struct xcan_device_stats *stats = &priv->stats;
	struct can_frame *cf = (struct can_frame *)&priv->rx_frame;
	// struct sk_buff *skb;
	u32 id_xcan, dlc, data[2] = {0, 0};
    unsigned long flags;

	// skb = alloc_can_skb(ndev, &cf);
	// if (unlikely(!skb)) {
	// 	stats->rx_dropped++;
	// 	return 0;
	// }

	/* Read a frame from Xilinx zynq CANPS */
	id_xcan = priv->read_reg(priv, XCAN_FRAME_ID_OFFSET(frame_base));
	dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base)) >>
				   XCAN_DLCR_DLC_SHIFT;

	/* Change Xilinx CAN data length format to socketCAN data format */
	cf->can_dlc = get_can_dlc(dlc);

	/* Change Xilinx CAN ID format to socketCAN ID format */
	if (id_xcan & XCAN_IDR_IDE_MASK) {
		/* The received frame is an Extended format frame */
		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
		cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
				XCAN_IDR_ID2_SHIFT;
		cf->can_id |= CAN_EFF_FLAG;
		if (id_xcan & XCAN_IDR_RTR_MASK)
			cf->can_id |= CAN_RTR_FLAG;
	} else {
		/* The received frame is a standard format frame */
		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
				XCAN_IDR_ID1_SHIFT;
		if (id_xcan & XCAN_IDR_SRR_MASK)
			cf->can_id |= CAN_RTR_FLAG;
	}

	/* DW1/DW2 must always be read to remove message from RXFIFO */
	data[0] = priv->read_reg(priv, XCAN_FRAME_DW1_OFFSET(frame_base));
	data[1] = priv->read_reg(priv, XCAN_FRAME_DW2_OFFSET(frame_base));

	if (!(cf->can_id & CAN_RTR_FLAG)) {
		/* Change Xilinx CAN data format to socketCAN data format */
		if (cf->can_dlc > 0)
			*(__be32 *)(cf->data) = cpu_to_be32(data[0]);
		if (cf->can_dlc > 4)
			*(__be32 *)(cf->data + 4) = cpu_to_be32(data[1]);
	}

	stats->rx_bytes += cf->can_dlc;
	stats->rx_packets++;
	// netif_receive_skb(skb);

    spin_lock_irqsave(&priv->rx_splock, flags);
    xcan_frame_to_msg(*(struct canfd_frame *)cf, &priv->rx_circ.msg[priv->rx_circ.head]);
    if (circ_buf_full(&priv->rx_circ)) {
        /* 丢弃最旧数据，位运算 & 比取模运算 % 快 10 倍以上（CPU 指令周期更少） */
        // priv->rx_circ.tail = (priv->rx_circ.tail + 1) % priv->rx_circ.size;
        priv->rx_circ.tail = (priv->rx_circ.tail + 1) & (priv->rx_circ.size - 1);
    }
    priv->rx_circ.head = (priv->rx_circ.head + 1) & (priv->rx_circ.size - 1);
    spin_unlock_irqrestore(&priv->rx_splock, flags);
    wake_up_interruptible(&priv->rx_wqh);

	return 1;
}

/**
 * xcanfd_rx -  Is called from CAN isr to complete the received
 *		frame  processing
 * @ndev:	Pointer to net_device structure
 * @frame_base:	Register offset to the frame to be read
 *
 * This function is invoked from the CAN isr(poll) to process the Rx frames. It
 * does minimal processing and invokes "netif_receive_skb" to complete further
 * processing.
 * Return: 1 on success and 0 on failure.
 */
static int xcanfd_rx(struct xcan_priv *priv, int frame_base)
{
	struct canfd_frame *cf = &priv->rx_frame;
	u32 id_xcan, dlc, data[2] = {0, 0}, dwindex = 0, i, dw_offset;
    unsigned long flags;    // 用于保存中断状态

	id_xcan = priv->read_reg(priv, XCAN_FRAME_ID_OFFSET(frame_base));
	dlc = priv->read_reg(priv, XCAN_FRAME_DLC_OFFSET(frame_base));

	/* Change Xilinx CANFD data length format to socketCAN data
	 * format
	 */
	if (dlc & XCAN_DLCR_EDL_MASK)
		cf->len = can_dlc2len((dlc & XCAN_DLCR_DLC_MASK) >>
				  XCAN_DLCR_DLC_SHIFT);
	else
		cf->len = get_can_dlc((dlc & XCAN_DLCR_DLC_MASK) >>
					  XCAN_DLCR_DLC_SHIFT);

	/* Change Xilinx CAN ID format to socketCAN ID format */
	if (id_xcan & XCAN_IDR_IDE_MASK) {
		/* The received frame is an Extended format frame */
		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
		cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
				XCAN_IDR_ID2_SHIFT;
		cf->can_id |= CAN_EFF_FLAG;
		if (id_xcan & XCAN_IDR_RTR_MASK)
			cf->can_id |= CAN_RTR_FLAG;
	} else {
		/* The received frame is a standard format frame */
		cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
				XCAN_IDR_ID1_SHIFT;
		if (!(dlc & XCAN_DLCR_EDL_MASK) && (id_xcan &
					XCAN_IDR_SRR_MASK))
			cf->can_id |= CAN_RTR_FLAG;
	}

	/* Check the frame received is FD or not*/
	if (dlc & XCAN_DLCR_EDL_MASK) {
		for (i = 0; i < cf->len; i += 4) {
			dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base) +
					(dwindex * XCANFD_DW_BYTES);
			data[0] = priv->read_reg(priv, dw_offset);
			*(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
			dwindex++;
		}
	} else {
		for (i = 0; i < cf->len; i += 4) {
			dw_offset = XCANFD_FRAME_DW_OFFSET(frame_base);
			data[0] = priv->read_reg(priv, dw_offset + i);
			*(__be32 *)(cf->data + i) = cpu_to_be32(data[0]);
		}
	}

    // 环形缓冲区操作
    spin_lock_irqsave(&priv->rx_splock, flags);
    // if (id_xcan & XCAN_IDR_IDE_MASK) {
    //     priv->rx_circ.msg[priv->rx_circ.head].fmt = 1;
    // } else {
    //     priv->rx_circ.msg[priv->rx_circ.head].fmt = 0;
    // }
    // if (id_xcan & XCAN_IDR_RTR_MASK) {
    //     priv->rx_circ.msg[priv->rx_circ.head].rtr = 1;
    // } else {
    //     priv->rx_circ.msg[priv->rx_circ.head].rtr = 0;
    // }
    // priv->rx_circ.msg[priv->rx_circ.head].id = ((cf->can_id & ~CAN_EFF_FLAG) & ~CAN_RTR_FLAG);
    // priv->rx_circ.msg[priv->rx_circ.head].dlc = cf->len;
    // if (dlc & XCAN_DLCR_EDL_MASK) {
    //     priv->rx_circ.msg[priv->rx_circ.head].flg = 1;
    // } else {
    //     priv->rx_circ.msg[priv->rx_circ.head].flg = 0;
    // }
    // for (i = 0; i < priv->rx_circ.msg[priv->rx_circ.head].dlc; i++) {
    //     priv->rx_circ.msg[priv->rx_circ.head].data[i] = cf->data[i];
    // }
    xcan_frame_to_msg(*cf, &priv->rx_circ.msg[priv->rx_circ.head]);

    if (circ_buf_full(&priv->rx_circ)) {
        /* 丢弃最旧数据，位运算 & 比取模运算 % 快 10 倍以上（CPU 指令周期更少） */
        // priv->rx_circ.tail = (priv->rx_circ.tail + 1) % priv->rx_circ.size;
        priv->rx_circ.tail = (priv->rx_circ.tail + 1) & (priv->rx_circ.size - 1);
    }
    priv->rx_circ.head = (priv->rx_circ.head + 1) & (priv->rx_circ.size - 1);
    spin_unlock_irqrestore(&priv->rx_splock, flags);
    wake_up_interruptible(&priv->rx_wqh);

    return 1;
}
/**
 * xcan_current_error_state - Get current error state from HW
 * @ndev:	Pointer to net_device structure
 *
 * Checks the current CAN error state from the HW. Note that this
 * only checks for ERROR_PASSIVE and ERROR_WARNING.
 *
 * Return:
 * ERROR_PASSIVE or ERROR_WARNING if either is active, ERROR_ACTIVE
 * otherwise.
 */
static enum can_state xcan_current_error_state(struct xcan_priv *priv)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	u32 status = priv->read_reg(priv, XCAN_SR_OFFSET);

	if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK)
		return CAN_STATE_ERROR_PASSIVE;
	else if (status & XCAN_SR_ERRWRN_MASK)
		return CAN_STATE_ERROR_WARNING;
	else
		return CAN_STATE_ERROR_ACTIVE;
}
/**
 * xcan_set_error_state - Set new CAN error state
 * @ndev:	Pointer to net_device structure
 * @new_state:	The new CAN state to be set
 * @cf:		Error frame to be populated or NULL
 *
 * Set new CAN error state for the device, updating statistics and
 * populating the error frame if given.
 */
static void xcan_set_error_state(struct xcan_priv *priv,
				 enum can_state new_state,
				 struct can_frame *cf)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET);
	u32 txerr = ecr & XCAN_ECR_TEC_MASK;
	u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT;
	enum can_state tx_state = txerr >= rxerr ? new_state : 0;
	enum can_state rx_state = txerr <= rxerr ? new_state : 0;

	/* non-ERROR states are handled elsewhere */
	if (WARN_ON(new_state > CAN_STATE_ERROR_PASSIVE))
		return;

	xcan_change_state(&priv->can, cf, tx_state, rx_state);

	if (cf) {
		cf->data[6] = txerr;
		cf->data[7] = rxerr;
	}
}
/**
 * xcan_update_error_state_after_rxtx - Update CAN error state after RX/TX
 * @ndev:	Pointer to net_device structure
 *
 * If the device is in a ERROR-WARNING or ERROR-PASSIVE state, check if
 * the performed RX/TX has caused it to drop to a lesser state and set
 * the interface state accordingly.
 */
static void xcan_update_error_state_after_rxtx(struct xcan_priv *priv)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	enum can_state old_state = priv->can.state;
	enum can_state new_state;

	/* changing error state due to successful frame RX/TX can only
	 * occur from these states
	 */
	if (old_state != CAN_STATE_ERROR_WARNING &&
	    old_state != CAN_STATE_ERROR_PASSIVE)
		return;

	new_state = xcan_current_error_state(priv);

	if (new_state != old_state) {
#if 0
		struct sk_buff *skb;
		struct can_frame *cf;

		skb = alloc_can_err_skb(ndev, &cf);

		xcan_set_error_state(priv, new_state, skb ? cf : NULL);

		if (skb) {
			struct net_device_stats *stats = &ndev->stats;

			stats->rx_packets++;
			stats->rx_bytes += cf->can_dlc;
			netif_rx(skb);
		}
#else
        struct can_frame *cf = (struct can_frame *)&priv->rx_frame;
        unsigned long flags;
        xcan_set_error_state(priv, new_state, cf);
        if (cf) {
            struct xcan_device_stats *stats = &priv->stats;

            stats->rx_packets++;
            stats->rx_bytes += cf->can_dlc;
            /* 环形缓冲区操作 */
            spin_lock_irqsave(&priv->rx_splock, flags);
            xcan_frame_to_msg(*(struct canfd_frame *)cf, &priv->rx_circ.msg[priv->rx_circ.head]);
            if (circ_buf_full(&priv->rx_circ)) {
                /* 丢弃最旧数据，位运算 & 比取模运算 % 快 10 倍以上（CPU 指令周期更少） */
                // priv->rx_circ.tail = (priv->rx_circ.tail + 1) % priv->rx_circ.size;
                priv->rx_circ.tail = (priv->rx_circ.tail + 1) & (priv->rx_circ.size - 1);
            }
            priv->rx_circ.head = (priv->rx_circ.head + 1) & (priv->rx_circ.size - 1);
            spin_unlock_irqrestore(&priv->rx_splock, flags);
            wake_up_interruptible(&priv->rx_wqh);
        }
#endif
	}
}
/* CAN device restart for bus-off recovery */
static void xcan_restart(struct xcan_priv *priv)
{
	// struct can_priv *priv = netdev_priv(dev);
	struct xcan_device_stats *stats = &priv->stats;
	// struct sk_buff *skb;
	struct can_frame *cf = (struct can_frame *)&priv->rx_frame;
	int err;
    unsigned long flags;

	// if (netif_carrier_ok(dev))
		dev_err(priv->dev, "Attempt to restart for bus-off recovery, but carrier is OK?");

	/* No synchronization needed because the device is bus-off and
	 * no messages can come in or go out.
	 */
	// can_flush_echo_skb(dev);

	/* send restart message upstream */
	// skb = alloc_can_err_skb(dev, &cf);
	if (!cf)
		goto restart;

	cf->can_id |= CAN_ERR_RESTARTED;

	stats->rx_packets++;
	stats->rx_bytes += cf->can_dlc;

	// netif_rx_ni(skb);
    spin_lock_irqsave(&priv->rx_splock, flags);
    xcan_frame_to_msg(*(struct canfd_frame *)&cf, &priv->rx_circ.msg[priv->rx_circ.head]);
    if (circ_buf_full(&priv->rx_circ)) {
        /* 丢弃最旧数据，位运算 & 比取模运算 % 快 10 倍以上（CPU 指令周期更少） */
        // priv->rx_circ.tail = (priv->rx_circ.tail + 1) % priv->rx_circ.size;
        priv->rx_circ.tail = (priv->rx_circ.tail + 1) & (priv->rx_circ.size - 1);
    }
    priv->rx_circ.head = (priv->rx_circ.head + 1) & (priv->rx_circ.size - 1);
    spin_unlock_irqrestore(&priv->rx_splock, flags);
    wake_up_interruptible(&priv->rx_wqh);

restart:
	dev_info(priv->dev, "restarted");
	priv->can.can_stats.restarts++;

	/* Now restart the device */
	// netif_carrier_on(dev);
	err = xcan_do_set_mode(priv, CAN_MODE_START);
	if (err) {
		dev_err(priv->dev, "Error %d during restart", err);
		// netif_carrier_off(dev);
	}
}
static void xcan_restart_work(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct xcan_priv *priv = container_of(dwork, struct xcan_priv,
					     restart_work);

	xcan_restart(priv);
}
/* CAN bus-off
 *
 * This functions should be called when the device goes bus-off to
 * tell the netif layer that no more packets can be sent or received.
 * If enabled, a timer is started to trigger bus-off recovery.
 */
void can_bus_off(struct net_device *dev)
{
	struct can_priv *priv = netdev_priv(dev);

	if (priv->restart_ms)
		netdev_info(dev, "bus-off, scheduling restart in %d ms",
			    priv->restart_ms);
	else
		netdev_info(dev, "bus-off");

	netif_carrier_off(dev);

	if (priv->restart_ms)
		schedule_delayed_work(&priv->restart_work,
				      msecs_to_jiffies(priv->restart_ms));
}
/**
 * xcan_err_interrupt - error frame Isr
 * @ndev:	net_device pointer
 * @isr:	interrupt status register value
 *
 * This is the CAN error interrupt and it will
 * check the the type of error and forward the error
 * frame to upper layers.
 */
static void xcan_err_interrupt(struct xcan_priv *priv, u32 isr)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	struct xcan_device_stats *stats = &priv->stats;
	struct can_frame cf = { };
	u32 err_status;

	err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
	priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);

	if (isr & XCAN_IXR_BSOFF_MASK) {
		priv->can.state = CAN_STATE_BUS_OFF;
		priv->can.can_stats.bus_off++;
		/* Leave device in Config Mode in bus-off state */
		priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
		xcan_bus_off(&priv->can);
		cf.can_id |= CAN_ERR_BUSOFF;
	} else {
		enum can_state new_state = xcan_current_error_state(priv);

		if (new_state != priv->can.state)
			xcan_set_error_state(priv, new_state, &cf);
	}

	/* Check for Arbitration lost interrupt */
	if (isr & XCAN_IXR_ARBLST_MASK) {
		priv->can.can_stats.arbitration_lost++;
		cf.can_id |= CAN_ERR_LOSTARB;
		cf.data[0] = CAN_ERR_LOSTARB_UNSPEC;
	}

	/* Check for RX FIFO Overflow interrupt */
	if (isr & XCAN_IXR_RXOFLW_MASK) {
		stats->rx_over_errors++;
		stats->rx_errors++;
		cf.can_id |= CAN_ERR_CRTL;
		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
	}

	/* Check for RX Match Not Finished interrupt */
	if (isr & XCAN_IXR_RXMNF_MASK) {
		stats->rx_dropped++;
		stats->rx_errors++;
		dev_err(priv->dev, "RX match not finished, frame discarded");
		cf.can_id |= CAN_ERR_CRTL;
		cf.data[1] |= CAN_ERR_CRTL_UNSPEC;
	}

	/* Check for error interrupt */
	if (isr & XCAN_IXR_ERROR_MASK) {
		bool berr_reporting = false;

		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
			berr_reporting = true;
			cf.can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
		}

		/* Check for Ack error interrupt */
		if (err_status & XCAN_ESR_ACKER_MASK) {
			stats->tx_errors++;
			if (berr_reporting) {
				cf.can_id |= CAN_ERR_ACK;
				cf.data[3] = CAN_ERR_PROT_LOC_ACK;
			}
		}

		/* Check for Bit error interrupt */
		if (err_status & XCAN_ESR_BERR_MASK) {
			stats->tx_errors++;
			if (berr_reporting) {
				cf.can_id |= CAN_ERR_PROT;
				cf.data[2] = CAN_ERR_PROT_BIT;
			}
		}

		/* Check for Stuff error interrupt */
		if (err_status & XCAN_ESR_STER_MASK) {
			stats->rx_errors++;
			if (berr_reporting) {
				cf.can_id |= CAN_ERR_PROT;
				cf.data[2] = CAN_ERR_PROT_STUFF;
			}
		}

		/* Check for Form error interrupt */
		if (err_status & XCAN_ESR_FMER_MASK) {
			stats->rx_errors++;
			if (berr_reporting) {
				cf.can_id |= CAN_ERR_PROT;
				cf.data[2] = CAN_ERR_PROT_FORM;
			}
		}

		/* Check for CRC error interrupt */
		if (err_status & XCAN_ESR_CRCER_MASK) {
			stats->rx_errors++;
			if (berr_reporting) {
				cf.can_id |= CAN_ERR_PROT;
				cf.data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
			}
		}
		priv->can.can_stats.bus_error++;
	}

	if (cf.can_id) {
#if 0
		struct can_frame *skb_cf;
		struct sk_buff *skb = alloc_can_err_skb(ndev, &skb_cf);

		if (skb) {
			skb_cf->can_id |= cf.can_id;
			memcpy(skb_cf->data, cf.data, CAN_ERR_DLC);
			stats->rx_packets++;
			stats->rx_bytes += CAN_ERR_DLC;
			netif_rx(skb);
		}
#else
        unsigned long flags;
        stats->rx_packets++;
        stats->rx_bytes += CAN_ERR_DLC;
        /* 环形缓冲区操作 */
        spin_lock_irqsave(&priv->rx_splock, flags);
        xcan_frame_to_msg(*(struct canfd_frame *)&cf, &priv->rx_circ.msg[priv->rx_circ.head]);
        if (circ_buf_full(&priv->rx_circ)) {
            /* 丢弃最旧数据，位运算 & 比取模运算 % 快 10 倍以上（CPU 指令周期更少） */
            // priv->rx_circ.tail = (priv->rx_circ.tail + 1) % priv->rx_circ.size;
            priv->rx_circ.tail = (priv->rx_circ.tail + 1) & (priv->rx_circ.size - 1);
        }
        priv->rx_circ.head = (priv->rx_circ.head + 1) & (priv->rx_circ.size - 1);
        spin_unlock_irqrestore(&priv->rx_splock, flags);
        wake_up_interruptible(&priv->rx_wqh);
#endif
	}

	dev_dbg(priv->dev, "%s: error status register:0x%x",
		   __func__, priv->read_reg(priv, XCAN_ESR_OFFSET));
}
/**
 * xcan_state_interrupt - It will check the state of the CAN device
 * @ndev:	net_device pointer
 * @isr:	interrupt status register value
 *
 * This will checks the state of the CAN device
 * and puts the device into appropriate state.
 */
static void xcan_state_interrupt(struct xcan_priv *priv, u32 isr)
{
	// struct xcan_priv *priv = netdev_priv(ndev);

	/* Check for Sleep interrupt if set put CAN device in sleep state */
	if (isr & XCAN_IXR_SLP_MASK)
		priv->can.state = CAN_STATE_SLEEPING;

	/* Check for Wake up interrupt if set put CAN device in Active state */
	if (isr & XCAN_IXR_WKUP_MASK)
		priv->can.state = CAN_STATE_ERROR_ACTIVE;
}
/**
 * xcan_rx_fifo_get_next_frame - Get register offset of next RX frame
 * @priv:	Driver private data structure
 *
 * Return: Register offset of the next frame in RX FIFO.
 */
static int xcan_rx_fifo_get_next_frame(struct xcan_priv *priv)
{
	int offset;

	if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI) {
		u32 fsr, mask;

		/* clear RXOK before the is-empty check so that any newly
		 * received frame will reassert it without a race
		 */
		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXOK_MASK);

		fsr = priv->read_reg(priv, XCAN_FSR_OFFSET);

		/* check if RX FIFO is empty */
		if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
			mask = XCAN_2_FSR_FL_MASK;
		else
			mask = XCAN_FSR_FL_MASK;

		if (!(fsr & mask))
			return -ENOENT;

		if (priv->devtype.flags & XCAN_FLAG_CANFD_2)
			offset =
			  XCAN_RXMSG_2_FRAME_OFFSET(fsr & XCAN_2_FSR_RI_MASK);
		else
			offset =
			  XCAN_RXMSG_FRAME_OFFSET(fsr & XCAN_FSR_RI_MASK);

	} else {
		/* check if RX FIFO is empty */
		if (!(priv->read_reg(priv, XCAN_ISR_OFFSET) &
		      XCAN_IXR_RXNEMP_MASK))
			return -ENOENT;

		/* frames are read from a static offset */
		offset = XCAN_RXFIFO_OFFSET;
	}

	return offset;
}
#endif  // (defined(EN_CAN) || defined(EN_CANFD))

// 打开设备
static int pcie_cdev_open(struct inode *inode, struct file *filp)
{
    // 获取与 inode 关联的字符设备
    struct char_dev_t *char_dev = container_of(inode->i_cdev, struct char_dev_t, cdev);
    struct pcie_cdev_t *pcie_dev = container_of(char_dev, struct pcie_cdev_t, char_dev[char_dev->index]);
    // struct irq_t *irq = &pcie_dev->irq;
    struct xcan_priv *priv = &pcie_dev->xcan[char_dev->index];
    int ret = 0;

    // 检查设备是否有效
    if (!priv || !priv->dev) {
        return -ENODEV;
    }
    // 记录设备指针
    filp->private_data = priv;
    // 尝试锁定设备
    if (mutex_lock_interruptible(&priv->lock)) {
        return -ERESTARTSYS;
    }
    dev_info(priv->dev, "Device open...");
    // ret = request_irq(irq->vector[priv->index], xcan_interrupt, irq->flags,
	// 		  char_dev->name, priv);
	// if (ret < 0) {
	// 	dev_err(priv->dev, "irq allocation for CAN failed");
	// 	goto unlock;
	// }

	ret = xcan_chip_start(priv);
	if (ret < 0) {
		dev_err(priv->dev, "xcan_chip_start failed!");
		goto err_irq;
	}

	return 0;

err_irq:
	// free_irq(irq->vector[priv->index], priv);

    mutex_unlock(&priv->lock);

    return ret;
}

// 关闭设备
static int pcie_cdev_release(struct inode *inode, struct file *filp)
{
    struct xcan_priv *priv = filp->private_data;

    if (priv) {
        mutex_lock(&priv->lock);
        dev_info(priv->dev, "Device closed");
        mutex_unlock(&priv->lock);
    }

    return 0;
}

// 读取设备
static ssize_t pcie_cdev_read(struct file *filp, char __user *buf, 
                             size_t count, loff_t *ppos)
{
    struct xcan_priv *priv = filp->private_data;
    // struct pcie_cdev_t *pcie_dev = container_of(&priv, struct pcie_cdev_t, xcan[priv->index]);
    ssize_t ret = 0;
    size_t read_len = 0;
    size_t head = 0;
    size_t tail = 0;
    size_t avail = 0;
    size_t cnt_to_end = 0;      /* 到缓冲区末尾的连续数据 */
    size_t first_len = 0;       /* 第一段长度 */
    size_t second_len = 0;      /* 第二段长度 */
    unsigned long flags;

    if (!priv || !priv->dev || !buf)
        return -EINVAL;
    if (*ppos >= priv->rx_circ.size)
        return -EFBIG;

    if (circ_buf_empty(&priv->rx_circ)) {
        if (wait_event_interruptible(priv->rx_wqh, !circ_buf_empty(&priv->rx_circ))) {
            dev_err(priv->dev, "Circular read buffer wait interrupted.");
            return -ERESTARTSYS;
        }
    }

    if (mutex_lock_interruptible(&priv->lock))
        return -ERESTARTSYS;

    spin_lock_irqsave(&priv->rx_splock, flags);
    head = priv->rx_circ.head;
    tail = priv->rx_circ.tail;
    avail = CIRC_CNT(head, tail, priv->rx_circ.size);
    if (avail == 0) {
        spin_unlock_irqrestore(&priv->rx_splock, flags);
        ret = 0;
        goto unlock;
    }
    /* 计算实际可读取字节数 */
    read_len = min(count, avail);
    cnt_to_end = CIRC_CNT_TO_END(head, tail, priv->rx_circ.size);
    /* 分段读取 */
    first_len = min(read_len, cnt_to_end);
    second_len = read_len - first_len;
    spin_unlock_irqrestore(&priv->rx_splock, flags);
    /* 复制第一段（缓冲区尾部） */
    if (first_len && copy_to_user(buf, &priv->rx_circ.msg[tail], first_len)) {
        ret = -EFAULT;
        goto unlock;
    }
    /* 复制第二段（缓冲区头部回绕） */
    if (second_len && copy_to_user(buf + first_len, &priv->rx_circ.msg[0], second_len)) {
        ret = -EFAULT;
        goto unlock;
    }
    /* 更新tail */
    spin_lock_irqsave(&priv->rx_splock, flags);
    priv->rx_circ.tail = (tail + read_len) & (priv->rx_circ.size - 1);
    /* 更新文件位置*/
    *ppos += read_len;
    ret = read_len;
    spin_unlock_irqrestore(&priv->rx_splock, flags);

    dev_info(priv->dev, "Read %zu bytes from offset %lld", 
           read_len, *ppos - read_len);

unlock:
    mutex_unlock(&priv->lock);

    return ret;
}

// 写入设备
static ssize_t pcie_cdev_write(struct file *filp, const char __user *buf, 
                              size_t count, loff_t *ppos)
{
    struct xcan_priv *priv = filp->private_data;
    // struct pcie_cdev_t *pcie_dev = container_of(&priv, struct pcie_cdev_t, xcan[priv->index]);
    ssize_t ret = 0;
    size_t write_len = 0;
    size_t head = 0;
    size_t tail = 0;
    size_t avail = 0;
    size_t cnt_to_end = 0;      /* 到缓冲区末尾的连续数据 */
    size_t first_len = 0;       /* 第一段长度 */
    size_t second_len = 0;      /* 第二段长度 */
    unsigned long flags;
    u32 i = 0;
    
    if (!priv || !priv->dev || !buf) {
        return -EINVAL;
    }
    if (mutex_lock_interruptible(&priv->lock)) {
        return -ERESTARTSYS;
    }
    if (*ppos >= priv->tx_circ.size) {
        ret = -EFBIG;
        goto unlock;
    }

    spin_lock_irqsave(&priv->tx_splock, flags);
    head = priv->tx_circ.head;
    tail = priv->tx_circ.tail;
    avail = CIRC_CNT(head, tail, priv->tx_circ.size);
    if (avail == 0) {
        spin_unlock_irqrestore(&priv->tx_splock, flags);
        ret = 0;
        goto unlock;
    }
    // 计算实际可写入字节数
    write_len = min(count, avail);
    cnt_to_end = CIRC_CNT_TO_END(head, tail, priv->tx_circ.size);
    /* 分段写入 */
    first_len = min(write_len, cnt_to_end);
    second_len = write_len - first_len;
    spin_unlock_irqrestore(&priv->tx_splock, flags);

    /* 复制第一段（缓冲区尾部） */
    if (first_len && copy_from_user(&priv->tx_circ.msg[head], buf, first_len)) {
        ret = -EFAULT;
        goto unlock;
    }
    /* 复制第二段（缓冲区头部回绕） */
    if (second_len && copy_from_user(&priv->tx_circ.msg[0], buf + first_len, second_len)) {
        ret = -EFAULT;
        goto unlock;
    }

    for (i = 0; i < first_len; i++) {
        xcan_msg_to_frame(priv->tx_circ.msg[tail + i], &priv->tx_frame);
        xcan_start_xmit(&priv->tx_frame, priv);
    }
    for (i = 0; i < second_len; i++) {
        xcan_msg_to_frame(priv->tx_circ.msg[i], &priv->tx_frame);
        xcan_start_xmit(&priv->tx_frame, priv);
    }

    spin_lock_irqsave(&priv->tx_splock, flags);
    priv->tx_circ.head = (head + write_len) & (priv->tx_circ.size - 1);
    priv->tx_circ.tail = (tail + write_len) & (priv->tx_circ.size - 1);
    spin_unlock_irqrestore(&priv->tx_splock, flags);

    // 更新文件位置
    *ppos += write_len;
    ret = write_len;

    dev_dbg(priv->dev, "Wrote %zu bytes to offset %lld", 
           write_len, *ppos - write_len);

unlock:
    mutex_unlock(&priv->lock);

    return ret;
}

// IOCTL 命令定义
#define PCIE_CDEV_MAGIC         'P'                                             // 魔术字符，标识设备驱动
#ifdef EN_IRQ
#define CMD_IRQ_ENABLE          _IO(PCIE_CDEV_MAGIC, 8)                         // 中断使能 指令
#define CMD_IRQ_DISABLE         _IO(PCIE_CDEV_MAGIC, 9)                         // 中断禁用 指令
#endif // EN_IRQ
#if (defined(EN_CAN) || defined(EN_CANFD))
#define CMD_CAN_READ_REG                _IOR(PCIE_CDEV_MAGIC, 10, struct reg_data_t)        // 读寄存器 指令
#define CMD_CAN_WRITE_REG               _IOW(PCIE_CDEV_MAGIC, 11, struct reg_data_t)        // 写寄存器 指令
#define CMD_CAN_READ_MSG                _IOW(PCIE_CDEV_MAGIC, 12, struct canfd_msg_t)       // 读取报文 指令
#define CMD_CAN_CLEAR_MSG               _IO(PCIE_CDEV_MAGIC, 13)                            // 清空报文 指令
#define CMD_CAN_SET_CTRLMODE            _IOW(PCIE_CDEV_MAGIC, 14, u32)                      // 读取报文 指令
#define CMD_CAN_GET_CTRLMODE            _IOR(PCIE_CDEV_MAGIC, 15, u32)                      // 读寄存器 指令
#define CMD_CAN_SET_BITTIMING           _IOW(PCIE_CDEV_MAGIC, 16, struct can_bittiming)     // 读取报文 指令
#define CMD_CAN_GET_BITTIMING           _IOR(PCIE_CDEV_MAGIC, 17, struct can_bittiming)     // 读寄存器 指令
#define CMD_CAN_SET_DATA_BITTIMING      _IOW(PCIE_CDEV_MAGIC, 18, struct can_bittiming)     // 读取报文 指令
#define CMD_CAN_GET_DATA_BITTIMING      _IOR(PCIE_CDEV_MAGIC, 19, struct can_bittiming)     // 读寄存器 指令
#define CMD_CAN_SET_FILTER              _IOW(PCIE_CDEV_MAGIC, 20, struct xcan_filter_t)     /* 设置帧过滤 */
#define CMD_CAN_SET_MODE                _IOW(PCIE_CDEV_MAGIC, 21, int)                      /* 设置模式 */
#endif // (defined(EN_CAN) || defined(EN_CANFD))

// 寄存器数据描述符
struct reg_data_t {
    u32 addr;
    u32 val;
};
// IOCTL 处理
static long pcie_cdev_ioctl(struct file *filp, unsigned int cmd, 
                          unsigned long arg)
{
    struct xcan_priv *priv = filp->private_data;
    struct pcie_cdev_t *pcie_dev = container_of(priv, struct pcie_cdev_t, xcan[priv->index]);
    struct reg_data_t reg_data;
    long ret = 0;
    u8 channel = 0;
    int mode = 0;
    
    if (!priv || !priv->dev) {
        return -ENODEV;
    }
    if (mutex_lock_interruptible(&priv->lock)) {    // 加锁
        return -ERESTARTSYS;
    }
    switch (cmd) {
#ifdef EN_IRQ
    case CMD_IRQ_ENABLE:
        // 中断使能
        iowrite32(0x01, pcie_dev->irq.reg_base + IRQ_MSI_MASK_REG);
        dev_info(pcie_dev->dev, "Interrupts enabled.");
        break;
    case CMD_IRQ_DISABLE:
        // 中断禁用
        iowrite32(0x00, pcie_dev->irq.reg_base + IRQ_MSI_MASK_REG);
        dev_info(pcie_dev->dev, "Interrupts disabled.");
        break;
#endif // EN_IRQ
#if (defined(EN_CAN) || defined(EN_CANFD))
    case CMD_CAN_READ_REG:    // 读寄存器 指令
        if (copy_from_user(&reg_data, (void __user *)arg, sizeof(reg_data)))
            return -EFAULT;
        // 须应用层下发通道
        channel = ((reg_data.addr >> CAN_FD_DEV_ID_SHIFT) & 0xFF) % DEV_NUM;
        reg_data.val = pcie_dev->xcan[channel].read_reg(&pcie_dev->xcan[channel], reg_data.addr);
        if (copy_to_user((void __user *)arg, &reg_data, sizeof(reg_data))) {
            ret = -EFAULT;
            break;
        }
        dev_info(pcie_dev->dev, "Read register 0x%x: 0x%x", 
                    reg_data.addr, reg_data.val);
        break;
    case CMD_CAN_WRITE_REG:   // 写寄存器 指令
        if (copy_from_user(&reg_data, (void __user *)arg, sizeof(reg_data)))
            return -EFAULT;
        channel = ((reg_data.addr >> CAN_FD_DEV_ID_SHIFT) & 0xFF) % DEV_NUM;
        pcie_dev->xcan[channel].write_reg(&pcie_dev->xcan[channel], reg_data.addr, reg_data.val);
        dev_info(pcie_dev->dev, "Write register 0x%x: 0x%x", 
                    reg_data.addr, reg_data.val);
        break;
    case CMD_CAN_READ_MSG:    // 读取报文 指令
        break;
    case CMD_CAN_CLEAR_MSG:   // 清空报文 指令
        for (channel = 0; channel < DEV_NUM; channel++) {
            pcie_dev->xcan[channel].rx_circ.size = CIRC_BUF_SIZE;
            pcie_dev->xcan[channel].rx_circ.head = 0;
            pcie_dev->xcan[channel].rx_circ.tail = 0;
            memset(pcie_dev->xcan[channel].rx_circ.msg, 0, sizeof(pcie_dev->xcan[channel].rx_circ.msg));
        }
        break;
    case CMD_CAN_SET_CTRLMODE:
        /* Set control mode */
        if (copy_from_user(&priv->can.ctrlmode, (void __user *)arg,
                           sizeof(priv->can.ctrlmode))) {
            ret = -EFAULT;
            goto unlock;
        }
        break;
    case CMD_CAN_GET_CTRLMODE:
        /* Get control mode */
        if (copy_to_user((void __user *)arg, &priv->can.ctrlmode,
                         sizeof(priv->can.ctrlmode))) {
            ret = -EFAULT;
            goto unlock;
        }
        break;
    case CMD_CAN_SET_BITTIMING:
        /* Set bit timing */
        if (copy_from_user(&priv->can.bittiming, (void __user *)arg,
                           sizeof(priv->can.bittiming))) {
            ret = -EFAULT;
            goto unlock;
        }
        ret = xcan_calc_bittiming(&priv->can, &priv->can.bittiming, priv->can.bittiming_const);
        if (0 > ret) {
            dev_err(priv->dev, "Calculate bittiming.bitrate=%d failed!", priv->can.bittiming.bitrate);
            goto unlock;
        }
        ret = set_reset_mode(priv);
        if (0 > ret) {
            goto unlock;
        }
        ret = xcan_set_bittiming(priv);
        if (0 > ret) {
            dev_err(priv->dev, "Set bittiming.bitrate=%d failed!", priv->can.bittiming.bitrate);
            goto unlock;
        }
        break;
    case CMD_CAN_GET_BITTIMING:
        /* Get bit timing */
        if (copy_to_user((void __user *)arg, &priv->can.bittiming,
                         sizeof(priv->can.bittiming))) {
            ret = -EFAULT;
            goto unlock;
        }
        break;
    case CMD_CAN_SET_DATA_BITTIMING:
        /* Set data bit timing (CAN FD) */
        if (copy_from_user(&priv->can.data_bittiming, (void __user *)arg,
                           sizeof(priv->can.data_bittiming))) {
            ret = -EFAULT;
            goto unlock;
        }
        ret = xcan_calc_bittiming(&priv->can, &priv->can.data_bittiming, priv->can.data_bittiming_const);
        if (0 > ret) {
            dev_err(priv->dev, "Calculate data_bittiming.bitrate=%d failed!", priv->can.data_bittiming.bitrate);
            goto unlock;
        }
        ret = set_reset_mode(priv);
        if (0 > ret) {
            goto unlock;
        }
        ret = xcan_set_bittiming(priv);
        if (0 > ret) {
            dev_err(priv->dev, "Set data_bittiming.bitrate=%d failed!", priv->can.data_bittiming.bitrate);
            goto unlock;
        }
        break;
    case CMD_CAN_GET_DATA_BITTIMING:
        /* Get data bit timing (CAN FD) */
        if (copy_to_user((void __user *)arg, &priv->can.data_bittiming,
                         sizeof(priv->can.data_bittiming))) {
            ret = -EFAULT;
            goto unlock;
        }
        break;
    case CMD_CAN_SET_FILTER:
        if (copy_from_user(&priv->filter, (void __user *)arg,
                           sizeof(priv->filter))) {
            ret = -EFAULT;
            goto unlock;
        }
        if (priv->devtype.flags & XCAN_FLAG_EXT_FILTERS)
            priv->write_reg(priv, XCAN_AFR_EXT_OFFSET, 0x00000000);
        if (priv->devtype.flags & XCAN_FLAG_CANFD_2) {
            priv->write_reg(priv, XCAN_AFR_2_ID_OFFSET, priv->filter.id);
            priv->write_reg(priv, XCAN_AFR_2_MASK_OFFSET, priv->filter.mask);
        }
        if (priv->devtype.flags & XCAN_FLAG_EXT_FILTERS)
            priv->write_reg(priv, XCAN_AFR_EXT_OFFSET, 0x00000001);
        break;
    case CMD_CAN_SET_MODE:
        if (copy_from_user(&mode, (void __user *)arg, sizeof(mode))) {
            ret = -EFAULT;
            goto unlock;
        }
        switch (mode) {
        case CAN_MODE_START:
            ret = xcan_chip_start(priv);
            if (ret < 0) {
                dev_err(priv->dev, "xcan_chip_start failed!\n");
                goto unlock;
            }
            break;
        default:
            ret = -EOPNOTSUPP;
            goto unlock;
        }
        break;
#endif // (defined(EN_CAN) || defined(EN_CANFD))
    default:
        ret = -ENOTTY;
        goto unlock;
        break;
    }

unlock:
    mutex_unlock(&pcie_dev->lock);

    return ret;
}

#ifdef EN_CDEV
static int char_dev_init(struct class *char_class, struct char_dev_t *char_dev, u8 index)
{
    int ret = 0;
    dev_t devno;

    char_dev->index = index;
    snprintf(char_dev->name, sizeof(char_dev->name), "%s%d", DRV_NAME, index);
    ret = alloc_chrdev_region(&devno, 0, 1, char_dev->name);
    if (ret) {
        dev_err(char_dev->dev, "Failed to allocate devno");
        goto err_dev_init;
    }
    char_dev->devno = devno;
    cdev_init(&char_dev->cdev, &pcie_cdev_fops);
    char_dev->cdev.owner = THIS_MODULE;
    ret = cdev_add(&char_dev->cdev, char_dev->devno, 1);
    if (ret) {
        dev_err(char_dev->dev, "Failed to add char_dev");
        goto err_unregister_dev;
    }
    device_create(char_class, NULL, char_dev->devno, NULL, "%s", char_dev->name);

    return 0;

err_unregister_dev:
    unregister_chrdev_region(char_dev->devno, 1);
err_dev_init:

    return ret;
}

static int char_dev_exit(struct class *char_class, struct char_dev_t *char_dev)
{
    int ret = 0;

    device_destroy(char_class, char_dev->devno);
    cdev_del(&char_dev->cdev);
    unregister_chrdev_region(char_dev->devno, 1);

    return ret;
}
#endif // EN_CDEV

#ifdef EN_IRQ
/**
 * xcan_tx_interrupt - Tx Done Isr
 * @ndev:	net_device pointer
 * @isr:	Interrupt status register value
 */
static void xcan_tx_interrupt(struct xcan_priv *priv, u32 isr)
{
	// struct xcan_priv *priv = netdev_priv(ndev);
	struct xcan_device_stats *stats = &priv->stats;
	unsigned int frames_in_fifo;
	int frames_sent = 1; /* TXOK => at least 1 frame was sent */
	unsigned long flags;
	int retries = 0;

	/* Synchronize with xmit as we need to know the exact number
	 * of frames in the FIFO to stay in sync due to the TXFEMP
	 * handling.
	 * This also prevents a race between netif_wake_queue() and
	 * netif_stop_queue().
	 */
	spin_lock_irqsave(&priv->tx_lock, flags);

	frames_in_fifo = priv->tx_head - priv->tx_tail;

	if (WARN_ON_ONCE(frames_in_fifo == 0)) {
		/* clear TXOK anyway to avoid getting back here */
		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
		spin_unlock_irqrestore(&priv->tx_lock, flags);
		return;
	}

	/* Check if 2 frames were sent (TXOK only means that at least 1
	 * frame was sent).
	 */
	if (frames_in_fifo > 1) {
		WARN_ON(frames_in_fifo > priv->tx_max);

		/* Synchronize TXOK and isr so that after the loop:
		 * (1) isr variable is up-to-date at least up to TXOK clear
		 *     time. This avoids us clearing a TXOK of a second frame
		 *     but not noticing that the FIFO is now empty and thus
		 *     marking only a single frame as sent.
		 * (2) No TXOK is left. Having one could mean leaving a
		 *     stray TXOK as we might process the associated frame
		 *     via TXFEMP handling as we read TXFEMP *after* TXOK
		 *     clear to satisfy (1).
		 */
		while ((isr & XCAN_IXR_TXOK_MASK) &&
		       !WARN_ON(++retries == 100)) {
			priv->write_reg(priv, XCAN_ICR_OFFSET,
					XCAN_IXR_TXOK_MASK);
			isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
		}

		if (isr & XCAN_IXR_TXFEMP_MASK) {
			/* nothing in FIFO anymore */
			frames_sent = frames_in_fifo;
		}
	} else {
		/* single frame in fifo, just clear TXOK */
		priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
	}

	while (frames_sent--) {
		// stats->tx_bytes += can_get_echo_skb(ndev, priv->tx_tail %
		// 				    priv->tx_max);
		priv->tx_tail++;
		stats->tx_packets++;
	}

	// netif_wake_queue(ndev);

	spin_unlock_irqrestore(&priv->tx_lock, flags);

	// can_led_event(ndev, CAN_LED_EVENT_TX);
	xcan_update_error_state_after_rxtx(priv);
}

/**
 * xcan_interrupt - CAN Isr
 * @irq:	irq number
 * @dev_id:	device id pointer
 *
 * This is the xilinx CAN Isr. It checks for the type of interrupt
 * and invokes the corresponding ISR.
 *
 * Return:
 * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
 */
static irqreturn_t xcan_interrupt(int irq, void *dev_id)
{
#if 0
    struct pcie_cdev_t *pdev = dev_id;
    struct irq_t *pirq = &pdev->irq;
    struct xcan_priv *priv = NULL;
    int irq_idx = -1;
    int i;
    u8 channel = 0;
    u32 status = 0;
    struct can_reg_t reg = {0};
    // u32 isr_errors;
    u32 rx_int_mask = xcan_rx_int_mask(priv);

    if (!pirq) {
        return IRQ_NONE;
    }
    // 确定中断索引 (仅对MSI-X/MSI重要)
    if (pirq->mode == PCI_IRQ_MSIX || pirq->mode == PCI_IRQ_MSI) {
        for (i = 0; i < pirq->num; i++) {
            if (pirq->vector[i] == irq) {
                irq_idx = i;
                break;
            }
        }
    } else {
        irq_idx = 0; // Legacy中断只有一个
    }
    dev_info(pirq->dev, "Interrupt %d handled (vector %d)", 
             irq, irq_idx);
    if (irq_idx < 0) {
        pr_err("Unknown interrupt %d", irq);
        return IRQ_NONE;
    }

    pirq->index = irq_idx;
    channel = ((pirq->index) % DEV_NUM);
    priv = &pdev->xcan[channel];
    // 索引中断向量
    switch (pirq->index) {
#ifdef EN_CANFD
        case IR1_VEC_MSI_CANFD_0:
        case IR1_VEC_MSI_CANFD_1:
        case IR1_VEC_MSI_CANFD_2:
        case IR1_VEC_MSI_CANFD_3:
        case IR1_VEC_MSI_CANFD_4:
        case IR1_VEC_MSI_CANFD_5:
        case IR1_VEC_MSI_CANFD_6:
        case IR1_VEC_MSI_CANFD_7:
        case IR1_VEC_MSI_CANFD_8:
        case IR1_VEC_MSI_CANFD_9:
            
            // 屏蔽 MSI 中断
            iowrite32(0x00, pirq->reg_base + IRQ_MSI_MASK_REG);

            
            reg.isr = priv->read_reg(priv, XCAN_ISR_OFFSET);      // 中断状态寄存器
            reg.ier = priv->read_reg(priv, XCAN_IER_OFFSET);      // 中断使能寄存器
            reg.sr = priv->read_reg(priv, XCAN_SR_OFFSET);        // 状态寄存器
            reg.ecr = priv->read_reg(priv, XCAN_ECR_OFFSET);      // 错误计数寄存器
            reg.esr = priv->read_reg(priv, XCAN_ESR_OFFSET);      // 错误状态寄存器
            // 查看是否本通道中断(busoff)
            if ((reg.isr & XCAN_IXR_BSOFF_MASK) && 
                (reg.ier & XCAN_IXR_BSOFF_MASK)) {
                dev_info(pirq->dev, "channel %d busoff error interrupt in.ISR=0x%x IER=0x%x SR=0x%x", 
                         channel, reg.isr, reg.ier, reg.sr);
                // 保存工作模式
                reg.brpr = priv->read_reg(priv, XCAN_BRPR_OFFSET);        // 波特率预分频寄存器
                reg.btr = priv->read_reg(priv, XCAN_BTR_OFFSET);          // 位定时寄存器
#ifdef EN_CANFD
                reg.fd.brpr = priv->read_reg(priv, XCAN_F_BRPR_OFFSET);   // 波特率预分频寄存器
                reg.fd.btr = priv->read_reg(priv, XCAN_F_BTR_OFFSET);     // 位定时寄存器
#endif // EN_CANFD
                // 清除中断
                priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_BSOFF_MASK);  // 中断清零寄存器
                // 需要复位,写复位寄存器
                priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);  // 软复位寄存器
                // 恢复工作模式
                priv->write_reg(priv, XCAN_IER_OFFSET, reg.ier);          // 中断使能寄存器(0x380?)
                priv->write_reg(priv, XCAN_BRPR_OFFSET, reg.brpr);        // 波特率预分频寄存器
                priv->write_reg(priv, XCAN_BTR_OFFSET, reg.btr);          // 位定时寄存器
#ifdef EN_CANFD
                priv->write_reg(priv, XCAN_F_BRPR_OFFSET, reg.fd.brpr);   // 波特率预分频寄存器
                priv->write_reg(priv, XCAN_F_BTR_OFFSET, reg.fd.btr);     // 位定时寄存器
#endif // EN_CANFD
                // 工作模式
                priv->write_reg(priv, XCAN_MSR_OFFSET, 0x00);                 // 模式选择寄存器
                // 进入工作模式
                priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);    // 模式选择寄存器
            }
            // 查看被动错误
            if (((reg.sr & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) && 
                (reg.isr & XCAN_IXR_ERROR_MASK) && 
                (reg.ier & XCAN_IXR_ERROR_MASK)) {
                dev_info(pirq->dev, "channel %d passive error interrupt in.ISR=0x%x IER=0x%x SR=0x%x", 
                         channel, reg.isr, reg.ier, reg.sr);
                // 保存工作模式
                reg.brpr = priv->read_reg(priv, XCAN_BRPR_OFFSET);        // 波特率预分频寄存器
                reg.btr = priv->read_reg(priv, XCAN_BTR_OFFSET);          // 位定时寄存器
#ifdef EN_CANFD
                reg.fd.brpr = priv->read_reg(priv, XCAN_F_BRPR_OFFSET);   // 波特率预分频寄存器
                reg.fd.btr = priv->read_reg(priv, XCAN_F_BTR_OFFSET);     // 位定时寄存器
#endif // EN_CANFD
                // 清除中断
                priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_ERROR_MASK);  // 中断清零寄存器
                // 需要复位,写复位寄存器
                priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);  // 软复位寄存器
                // 恢复工作模式
                priv->write_reg(priv, XCAN_IER_OFFSET, reg.ier);          // 中断使能寄存器(0x380?)
                priv->write_reg(priv, XCAN_BRPR_OFFSET, reg.brpr);        // 波特率预分频寄存器
                priv->write_reg(priv, XCAN_BTR_OFFSET, reg.btr);          // 位定时寄存器
#ifdef EN_CANFD
                priv->write_reg(priv, XCAN_F_BRPR_OFFSET, reg.fd.brpr);   // 波特率预分频寄存器
                priv->write_reg(priv, XCAN_F_BTR_OFFSET, reg.fd.btr);     // 位定时寄存器
#endif // EN_CANFD
                // 工作模式
                priv->write_reg(priv, XCAN_MSR_OFFSET, 0x00);                 // 模式选择寄存器
                // 进入工作模式
                priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);    // 模式选择寄存器
            }
            // 其他错误
            if (((reg.sr & XCAN_SR_ESTAT_MASK) != XCAN_SR_ESTAT_MASK) && 
                (reg.isr & XCAN_IXR_ERROR_MASK) && 
                (reg.ier & XCAN_IXR_ERROR_MASK)) {
                dev_info(pirq->dev, "channel %d interrupt in.ISR=0x%x IER=0x%x SR=0x%x", 
                         channel, reg.isr, reg.ier, reg.sr);
                // 清错误状态
                priv->write_reg(priv, XCAN_ESR_OFFSET, reg.esr);          // 错误状态寄存器
                // 清除中断
                priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_ERROR_MASK);  // 中断清零寄存器
            }
            // // 查看是否本通道中断(中断已使能且已触发)
            // if ((reg.isr & XCAN_IXR_RXNEMP_MASK) && 
            //     (reg.ier & XCAN_IXR_RXNEMP_MASK)) {
            //     dev_info(pirq->dev, "channel %d receive interrupt in.", channel);
            //     // 屏蔽相关中断位
            //     reg.ier &= 0x00000F7F;
            //     // 禁用中断
            //     priv->write_reg(priv, XCAN_IER_OFFSET, reg.ier);          // 中断使能寄存器
            //     // 中断内调度工作队列
            //     schedule_work(&pirq->work);
            // }
            /* Check for the type of receive interrupt and Processing it */
            if (reg.isr & rx_int_mask) {
                reg.ier = priv->read_reg(priv, XCAN_IER_OFFSET);
                reg.ier &= ~rx_int_mask;
                priv->write_reg(priv, XCAN_IER_OFFSET, reg.ier);
                // 中断内调度工作队列
                schedule_work(&pirq->work);
            }

            // 使能 MSI 中断
            iowrite32(0x01, pirq->reg_base + IRQ_MSI_MASK_REG);
            break;
#endif // EN_AD
        default:
            // 检查中断状态
            status = ioread32(pirq->reg_base + 0x4); // 状态寄存器
            if (!(status & (1 << irq_idx))) {
                return IRQ_NONE; // 不是我们的中断
            }
            // 清除中断标志
            iowrite32(status | (1 << irq_idx), pirq->reg_base + 0x4);
            // 更新中断计数器
            atomic_inc(&pirq->count);
            // 唤醒等待进程
            wake_up_interruptible(&priv->rx_wqh);
            // 调度工作队列
            schedule_work(&pirq->work);
            // 记录中断事件
            dev_dbg(pirq->dev, "Interrupt %d handled (vector %d)", 
                    irq, irq_idx);
            break;
    }
#else

#endif
	// struct net_device *ndev = (struct xcan_priv *)dev_id;
	struct xcan_priv *priv = (struct xcan_priv *)dev_id;
    // struct pcie_cdev_t *pdev = container_of(priv, struct pcie_cdev_t, xcan[priv->index]);
    // struct irq_t *pirq = &pdev->irq;
	u32 isr, ier;
	u32 isr_errors;
	u32 rx_int_mask = xcan_rx_int_mask(priv);

    // for (i = 0; i < pirq->num; i++) {
    //     if (pirq->vector[i] == irq) {
    //         pirq->index = i;
    //         break;
    //     }
    // }

	/* Get the interrupt status from Xilinx CAN */
	isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
	if (!isr)
		return IRQ_NONE;

	/* Check for the type of interrupt and Processing it */
	if (isr & (XCAN_IXR_SLP_MASK | XCAN_IXR_WKUP_MASK)) {
		priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_SLP_MASK |
				XCAN_IXR_WKUP_MASK));
		xcan_state_interrupt(priv, isr);
	}

	/* Check for Tx interrupt and Processing it */
	if (isr & XCAN_IXR_TXOK_MASK)
		xcan_tx_interrupt(priv, isr);

	/* Check for the type of error interrupt and Processing it */
	isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
			    XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK |
			    XCAN_IXR_RXMNF_MASK);
	if (isr_errors) {
		priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors);
		xcan_err_interrupt(priv, isr);
	}

	/* Check for the type of receive interrupt and Processing it */
	if (isr & rx_int_mask) {
		ier = priv->read_reg(priv, XCAN_IER_OFFSET);
		ier &= ~rx_int_mask;
		priv->write_reg(priv, XCAN_IER_OFFSET, ier);
		// napi_schedule(&priv->napi);
		schedule_work(&priv->work);
	}

	return IRQ_HANDLED;
}

// 工作队列处理函数(中断下半部)
static void work_queue_handler(struct work_struct *work)
{
    // struct irq_t *irq = container_of(work, struct irq_t, work);
    // struct pcie_cdev_t *pdev = container_of(irq, struct pcie_cdev_t, irq);
    // int channel = irq->index;
    // struct xcan_priv *priv = &pdev->xcan[channel];
    struct xcan_priv *priv = container_of(work, struct xcan_priv, work);
    int quota = 64;
    u32 ier = 0;
    int work_done = 0;
    int frame_offset = 0;

	while ((frame_offset = xcan_rx_fifo_get_next_frame(priv)) >= 0 &&
	       (work_done < quota)) {
		if (xcan_rx_int_mask(priv) & XCAN_IXR_RXOK_MASK)
			work_done += xcanfd_rx(priv, frame_offset);
		else
			work_done += xcan_rx(priv, frame_offset);

		if (priv->devtype.flags & XCAN_FLAG_RX_FIFO_MULTI)
			/* increment read index */
			priv->write_reg(priv, XCAN_FSR_OFFSET,
					XCAN_FSR_IRI_MASK);
		else
			/* clear rx-not-empty (will actually clear only if
			 * empty)
			 */
			priv->write_reg(priv, XCAN_ICR_OFFSET,
					XCAN_IXR_RXNEMP_MASK);
	}

	if (work_done) {
		// can_led_event(ndev, CAN_LED_EVENT_RX);
		xcan_update_error_state_after_rxtx(priv);
	}

	if (work_done < quota) {
		// if (napi_complete_done(napi, work_done)) {
			ier = priv->read_reg(priv, XCAN_IER_OFFSET);
			ier |= xcan_rx_int_mask(priv);
			priv->write_reg(priv, XCAN_IER_OFFSET, ier);
		// }
	}
	// return work_done;

    // 这里执行需要在进程上下文中处理的任务
    dev_info(priv->dev, "CANFD interrupt handled.");
    // 注意：在这个函数中，可以安全地调用可能睡眠的函数
}

// 初始化中断系统
static int drv_init_irq(struct irq_t *irq)
{
    struct pcie_cdev_t *priv = container_of(irq, struct pcie_cdev_t, irq);
    struct pci_dev *pdev = container_of(priv->dev, struct pci_dev, dev);
    int ret = 0, i;
    int max_vecs = 0;
    char irq_name[32] = {0};

    atomic_set(&irq->count, 0);
    irq->mode = 0;
    // 尝试使用 MSI-X
    max_vecs = IRQ_MAX_VEC_MSIX;
    ret = pci_alloc_irq_vectors(pdev, 1, max_vecs, PCI_IRQ_MSIX);
    if (ret > 0) {
        irq->num = ret;
        irq->mode = PCI_IRQ_MSIX;
        dev_info(irq->dev, "Using MSI-X with %d vectors", irq->num);
        goto setup_irqs;
    }
    // 尝试使用 MSI
    max_vecs = IRQ_MAX_VEC_MSI;
    ret = pci_alloc_irq_vectors(pdev, 1, max_vecs, PCI_IRQ_MSI);
    if (ret > 0) {
        irq->num = ret;
        irq->mode = PCI_IRQ_MSI;
        dev_info(irq->dev, "Using MSI with %d vectors", irq->num);
        goto setup_irqs;
    }
    // 使用 Legacy 中断
    max_vecs = IRQ_MAX_VEC_LGCY;
    ret = pci_alloc_irq_vectors(pdev, 1, max_vecs, PCI_IRQ_LEGACY);
    if (ret < 0) {
        dev_err(irq->dev, "Failed to allocate IRQ vectors (%d)", ret);
        return ret;
    }
    irq->num = 1;
    irq->mode = PCI_IRQ_LEGACY;
    dev_info(irq->dev, "Using legacy INTx interrupt");

    if (irq->num < IRQ_VECTOR_NUM) {
        dev_err(irq->dev, "IRQ vector number(%d/%d) error", irq->num, IRQ_VECTOR_NUM);
    } else {
        irq->num = IRQ_VECTOR_NUM;
    }

setup_irqs:
    if (PCI_IRQ_LEGACY == irq->mode)
        irq->flags = IRQF_SHARED;
    else
        irq->flags = 0;
    // 获取中断号并注册处理程序
    for (i = IRQ_VECTOR_START; i < irq->num; i++) {
        irq->vector[i] = pci_irq_vector(pdev, i);
        if (irq->vector[i] < 0) {
            dev_err(irq->dev, "Invalid IRQ vector for index %d", i);
            ret = -EINVAL;
            goto free_irq_vectors;
        }
        // 动态生成带编号的中断名称
        snprintf(irq_name, sizeof(irq_name), "%s%d", IRQ_NAME, i);
        // 注册中断处理程序
        ret = request_irq(irq->vector[i], xcan_interrupt, 
                          irq->flags,
                          irq_name, &priv->xcan[(i - 1) % DEV_NUM]);
        if (ret) {
            dev_err(irq->dev, "Failed to request IRQ %d for vector %d",
                    irq->vector[i], i);
            goto free_irqs;
        }
    }

    return 0;

free_irqs:
    // 清理已分配的中断
    while (i-- > 0) {
        free_irq(irq->vector[i], priv);
    }
free_irq_vectors:
    pci_free_irq_vectors(pdev);
    return ret;
}

// 中断系统清理资源
static void drv_exit_irq(struct irq_t *irq)
{
    struct pcie_cdev_t *priv = container_of(irq, struct pcie_cdev_t, irq);
    struct pci_dev *pdev = container_of(priv->dev, struct pci_dev, dev);
    int i;

    for (i = IRQ_VECTOR_START; i < irq->num; i++) {
        free_irq(irq->vector[i], priv);
    }
    pci_free_irq_vectors(pdev);
    irq->num = 0;
    irq->mode = 0;
}
#endif // EN_IRQ


#if (defined(EN_CAN) || defined(EN_CANFD))
// CANFD初始化
static int drv_init_canfd(struct xcan_priv *priv, u8 index)
{
    struct pcie_cdev_t *pdev = container_of(priv, struct pcie_cdev_t, xcan[index]);
    int ret = 0;
    const struct xcan_devtype_data *devtype = &xcan_canfd2_data;

    priv->dev = pdev->dev;
    priv->can.bittiming_const = devtype->bittiming_const;
    // priv->can.do_set_mode = xcan_do_set_mode;
    // priv->can.do_get_berr_counter = xcan_get_berr_counter;
    priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
                    CAN_CTRLMODE_BERR_REPORTING;
    if (devtype->cantype == XAXI_CANFD_2_0)
        priv->can.data_bittiming_const =
            &xcan_data_bittiming_const_canfd2;
    if (devtype->cantype == XAXI_CANFD ||
        devtype->cantype == XAXI_CANFD_2_0)
        priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
    priv->reg_base = pdev->bar[PCI_BAR0];
    priv->devtype = *devtype;
    priv->index = index;

    priv->read_reg = xcan_read_reg_le;
    priv->write_reg = xcan_write_reg_le;

    spin_lock_init(&priv->rx_splock);            // 自旋锁初始化
    init_waitqueue_head(&priv->rx_wqh);        // 初始化等待队列
    priv->rx_circ.size = CIRC_BUF_SIZE;
    priv->rx_circ.head = 0;
    priv->rx_circ.tail = 0;
    memset(priv->rx_circ.msg, 0, sizeof(priv->rx_circ.msg));

    priv->restart_ms = 500;
    INIT_DELAYED_WORK(&priv->restart_work, xcan_restart_work);

    // 初始化工作队列
    INIT_WORK(&priv->work, work_queue_handler);

    return ret;
}
#endif  // (defined(EN_CAN) || defined(EN_CANFD))

// PCI 设备探测函数
static int pcie_cdev_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
    struct pcie_cdev_t *priv;
    int ret = 0;
    u8 i = 0;

    dev_info(&pdev->dev, "Device: %04x:%04x at %s", 
             pdev->vendor, pdev->device, pci_name(pdev));

    // 检查设备是否已初始化
    if (pci_get_drvdata(pdev)) {
        dev_info(&pdev->dev, "Device already initialized");
        return -EBUSY;
    }
    // 分配设备结构
    priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
    if (!priv)
        return -ENOMEM;
    // 保存dev设备
    priv->dev = &pdev->dev;
    pci_set_drvdata(pdev, priv);
    // 生成唯一设备名称（使用PCI位置）
    // snprintf(priv->name, sizeof(priv->name), "pcie_cdev_%04x:%02x:%02x.%d",
    //          pci_domain_nr(pdev->bus), pdev->bus->number,
    //          PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
    snprintf(priv->name, sizeof(priv->name), "%s", DRV_NAME);
    // 初始化互斥锁
    mutex_init(&priv->lock);
    // 启用PCI设备
    ret = pci_enable_device(pdev);
    if (ret) {
        dev_err(priv->dev, "Failed to enable PCI device");
        goto err_free_dev;
    }
    // 请求内存区域
    ret = pci_request_regions(pdev, priv->name);
    if (ret) {
        dev_err(priv->dev, "Failed to request regions");
        goto err_disable_dev;
    }
    // 初始化所有 BAR 指针为 NULL
    for (i = 0; i < PCI_STD_NUM_BARS; i++) {
        priv->bar[i] = NULL;
    }
    // 检查并映射所有 BAR
    for (i = 0; i < PCI_STD_NUM_BARS; i++) {
        priv->bar_len[i] = pci_resource_len(pdev, i);
        // BAR0 必须有有效长度
        if (i == PCI_BAR0 && priv->bar_len[i] == 0) {
            dev_err(priv->dev, "Invalid BAR0 size");
            ret = -EIO;
            goto err_release_regions;
        }
        // 只映射长度非 0 的 BAR
        if (priv->bar_len[i] > 0) {
            priv->bar[i] = pci_ioremap_bar(pdev, i);
            if (!priv->bar[i]) {
                dev_err(priv->dev, "Failed to map BAR%d", i);
                ret = -ENOMEM;
                goto err_unmap_bars;
            }
        } else {
            dev_info(priv->dev, "BAR%d.len=%lld", i, priv->bar_len[i]);
        }
    }

    pci_set_master(pdev);
#ifdef EN_IRQ
    // 初始化中断系统
    priv->irq.dev = priv->dev;
    priv->irq.reg_base = priv->bar[PCI_BAR0];
    ret = drv_init_irq(&priv->irq);
    if (ret) {
        dev_err(priv->dev, "Failed to initialize interrupts!");
        goto err_unmap_bars;
    }
#endif // EN_IRQ
#ifdef EN_CDEV
    priv->char_class = class_create(THIS_MODULE, DRV_NAME);
    if (IS_ERR(priv->char_class)) {
        ret = PTR_ERR(priv->char_class);
        dev_err(priv->dev, "Failed to create class");
        goto err_cleanup_irq;
    }
    for (i = 0; i < DEV_NUM; i++) {
        priv->char_dev[i].dev = priv->dev;
        ret = char_dev_init(priv->char_class, &priv->char_dev[i], i);
        if (ret) {
            dev_err(priv->dev, "Failed to initialize char device!");
            goto err_class_destroy;
        }
    }
#endif // EN_CDEV
    dev_info(priv->dev, "PCIe character device %s initialized", priv->name);
    dev_info(priv->dev, "BAR%d size: %pa bytes", PCI_BAR0, &priv->bar_len[PCI_BAR0]);
#ifdef EN_IRQ
    dev_info(priv->dev, "Using %s with %d interrupt vectors",
             priv->irq.mode == PCI_IRQ_MSIX ? "MSI-X" :
             priv->irq.mode == PCI_IRQ_MSI ? "MSI" : "Legacy",
             priv->irq.num);
#endif // EN_IRQ
#if (defined(EN_CAN) || defined(EN_CANFD))
    for (i = 0; i < DEV_NUM; i++) {
        drv_init_canfd(&priv->xcan[i], i);       // 初始化 CANFD
    }
#endif // (defined(EN_CAN) || defined(EN_CANFD))

    return 0;

// 错误处理路径
err_class_destroy:
    class_destroy(priv->char_class);
err_cleanup_irq:
#ifdef EN_IRQ
    drv_exit_irq(&priv->irq);
#endif // EN_IRQ
err_unmap_bars:
    // 逆序释放已映射的 BAR
    while (i--) {
        if (priv->bar[i])
            iounmap(priv->bar[i]);
    }
err_release_regions:
    pci_release_regions(pdev);
err_disable_dev:
    pci_disable_device(pdev);
err_free_dev:
    // devm 会自动释放内存

    return ret;
}

// PCI 设备移除函数
static void pcie_cdev_remove(struct pci_dev *pdev)
{
    struct pcie_cdev_t *priv = pci_get_drvdata(pdev);
    u8 i = 0;

    if (!priv) {
        return;
    }
#ifdef EN_CDEV
    for (i = 0; i < DEV_NUM; i++) {
        // 字符设备 清理资源
        char_dev_exit(priv->char_class, &priv->char_dev[i]);
    }
    dev_info(priv->dev, "char_dev_exit done");
    class_destroy(priv->char_class);
    dev_info(priv->dev, "class_destroy done");
#endif // EN_CDEV
#ifdef EN_IRQ
    // 中断系统 清理资源
    drv_exit_irq(&priv->irq);
    dev_info(priv->dev, "drv_exit_irq done");
#endif // EN_IRQ

    // 取消寄存器映射
    for (i = 0; i < PCI_STD_NUM_BARS; i++) {
        if (priv->bar[i]) {
            pci_iounmap(pdev, priv->bar[i]);
        }
    }
    dev_info(priv->dev, "pci_iounmap done");
    // 释放PCI区域
    pci_release_regions(pdev);
    dev_info(priv->dev, "pci_release_regions done");
    // 禁用PCI设备
    pci_disable_device(pdev);
    dev_info(priv->dev, "pci_disable_device done");
    // 销毁互斥锁
    mutex_destroy(&priv->lock);

    dev_info(priv->dev, "PCIe character device %s removed", priv->name);
}

// PCI 设备ID表
static const struct pci_device_id pcie_cdev_ids[] = {
    { PCI_DEVICE(0x10ee, 0x9021) },     // Xilinx 示例设备
    { PCI_DEVICE(0x0755, 0x0755) },     // Pango 设备
    { 0, }  // 结束标记
};
MODULE_DEVICE_TABLE(pci, pcie_cdev_ids);

// PCI 驱动结构
static struct pci_driver pcie_cdev_driver = {
    .name = DRV_NAME,
    .id_table = pcie_cdev_ids,
    .probe = pcie_cdev_probe,
    .remove = pcie_cdev_remove,
};

// 模块初始化和退出
static int __init pcie_cdev_init(void)
{
    int ret;
    
    ret = pci_register_driver(&pcie_cdev_driver);
    if (ret) {
        pr_err("Failed to register PCI driver");
    } else {
        pr_info("PCIe character device driver loaded");
    }
    
    return ret;
}

static void __exit pcie_cdev_exit(void)
{
    pci_unregister_driver(&pcie_cdev_driver);
    pr_info("PCIe character device driver unloaded");
}

module_init(pcie_cdev_init);
module_exit(pcie_cdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jason");
MODULE_DESCRIPTION("PCIe Character Device Driver");
MODULE_VERSION("0.1");
